Commit 2db53400 authored by dmaclach@chromium.org's avatar dmaclach@chromium.org

Revert 96327 - Switch over to using SkRegions to calculate dirty areas.

BUG=91619
TEST=Set up a remoting sesssion and make sure it works.

Review URL: http://codereview.chromium.org/7491070

TBR=dmaclach@chromium.org
Review URL: http://codereview.chromium.org/7622002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96328 0039d316-1c4b-4281-b951-d872f2087c98
parent 274e372a
...@@ -5,9 +5,6 @@ include_rules = [ ...@@ -5,9 +5,6 @@ include_rules = [
"-remoting", "-remoting",
"+remoting/base", "+remoting/base",
"+remoting/proto", "+remoting/proto",
"+skia/config",
"+skia/ext",
"+third_party/GTM", "+third_party/GTM",
"+third_party/GTM/AppKit", "+third_party/GTM/AppKit",
"+third_party/skia/include/core",
] ]
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -17,6 +17,7 @@ CaptureData::CaptureData(const DataPlanes &data_planes, ...@@ -17,6 +17,7 @@ CaptureData::CaptureData(const DataPlanes &data_planes,
const gfx::Size& size, const gfx::Size& size,
media::VideoFrame::Format format) media::VideoFrame::Format format)
: data_planes_(data_planes), : data_planes_(data_planes),
dirty_rects_(),
size_(size), size_(size),
pixel_format_(format), pixel_format_(format),
capture_time_ms_(0), capture_time_ms_(0),
......
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "third_party/skia/include/core/SkRegion.h" #include "remoting/base/types.h"
#include "ui/gfx/size.h"
namespace remoting { namespace remoting {
...@@ -31,11 +30,12 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> { ...@@ -31,11 +30,12 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> {
const gfx::Size& size, const gfx::Size& size,
media::VideoFrame::Format format); media::VideoFrame::Format format);
// Get the data_planes data of the previous capture. // Get the data_planes data of the last capture.
const DataPlanes& data_planes() const { return data_planes_; } const DataPlanes& data_planes() const { return data_planes_; }
// Get the dirty region from the previous capture. // Get the list of updated rectangles in the last capture. The result is
const SkRegion& dirty_region() const { return dirty_region_; } // written into |rects|.
const InvalidRects& dirty_rects() const { return dirty_rects_; }
// Return the size of the image captured. // Return the size of the image captured.
gfx::Size size() const { return size_; } gfx::Size size() const { return size_; }
...@@ -44,7 +44,7 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> { ...@@ -44,7 +44,7 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> {
media::VideoFrame::Format pixel_format() const { return pixel_format_; } media::VideoFrame::Format pixel_format() const { return pixel_format_; }
// Mutating methods. // Mutating methods.
SkRegion& mutable_dirty_region() { return dirty_region_; } InvalidRects& mutable_dirty_rects() { return dirty_rects_; }
// Return the time spent on capturing. // Return the time spent on capturing.
int capture_time_ms() const { return capture_time_ms_; } int capture_time_ms() const { return capture_time_ms_; }
...@@ -62,7 +62,7 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> { ...@@ -62,7 +62,7 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> {
private: private:
const DataPlanes data_planes_; const DataPlanes data_planes_;
SkRegion dirty_region_; InvalidRects dirty_rects_;
gfx::Size size_; gfx::Size size_;
media::VideoFrame::Format pixel_format_; media::VideoFrame::Format pixel_format_;
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <deque> #include <deque>
#include <stdlib.h> #include <stdlib.h>
#include "base/memory/scoped_ptr.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "remoting/base/base_mock_objects.h" #include "remoting/base/base_mock_objects.h"
#include "remoting/base/codec_test.h" #include "remoting/base/codec_test.h"
...@@ -13,18 +12,19 @@ ...@@ -13,18 +12,19 @@
#include "remoting/base/encoder.h" #include "remoting/base/encoder.h"
#include "remoting/base/util.h" #include "remoting/base/util.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"
static const int kWidth = 320; static const int kWidth = 320;
static const int kHeight = 240; static const int kHeight = 240;
static const int kBytesPerPixel = 4; static const int kBytesPerPixel = 4;
// Some sample rects for testing. // Some sample rects for testing.
static const SkIRect kTestRects[] = { static const gfx::Rect kTestRects[] = {
SkIRect::MakeXYWH(0, 0, kWidth, kHeight), gfx::Rect(0, 0, kWidth, kHeight),
SkIRect::MakeXYWH(0, 0, kWidth / 2, kHeight / 2), gfx::Rect(0, 0, kWidth / 2, kHeight / 2),
SkIRect::MakeXYWH(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), gfx::Rect(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2),
SkIRect::MakeXYWH(16, 16, 16, 16), gfx::Rect(16, 16, 16, 16),
SkIRect::MakeXYWH(128, 64, 32, 32), gfx::Rect(128, 64, 32, 32),
}; };
namespace remoting { namespace remoting {
...@@ -58,10 +58,10 @@ class EncoderMessageTester { ...@@ -58,10 +58,10 @@ class EncoderMessageTester {
++begin_rect_; ++begin_rect_;
if (strict_) { if (strict_) {
SkIRect rect = rects_.front(); gfx::Rect rect = rects_.front();
rects_.pop_front(); rects_.pop_front();
EXPECT_EQ(rect.fLeft, packet->format().x()); EXPECT_EQ(rect.x(), packet->format().x());
EXPECT_EQ(rect.fTop, packet->format().y()); EXPECT_EQ(rect.y(), packet->format().y());
EXPECT_EQ(rect.width(), packet->format().width()); EXPECT_EQ(rect.width(), packet->format().width());
EXPECT_EQ(rect.height(), packet->format().height()); EXPECT_EQ(rect.height(), packet->format().height());
} }
...@@ -93,7 +93,7 @@ class EncoderMessageTester { ...@@ -93,7 +93,7 @@ class EncoderMessageTester {
strict_ = strict; strict_ = strict;
} }
void AddRects(const SkIRect* rects, int count) { void AddRects(const gfx::Rect* rects, int count) {
rects_.insert(rects_.begin() + rects_.size(), rects, rects + count); rects_.insert(rects_.begin() + rects_.size(), rects, rects + count);
added_rects_ += count; added_rects_ += count;
} }
...@@ -111,7 +111,7 @@ class EncoderMessageTester { ...@@ -111,7 +111,7 @@ class EncoderMessageTester {
State state_; State state_;
bool strict_; bool strict_;
std::deque<SkIRect> rects_; std::deque<gfx::Rect> rects_;
DISALLOW_COPY_AND_ASSIGN(EncoderMessageTester); DISALLOW_COPY_AND_ASSIGN(EncoderMessageTester);
}; };
...@@ -152,7 +152,7 @@ class DecoderTester { ...@@ -152,7 +152,7 @@ class DecoderTester {
capture_data_ = data; capture_data_ = data;
} }
void AddRects(const SkIRect* rects, int count) { void AddRects(const gfx::Rect* rects, int count) {
rects_.insert(rects_.begin() + rects_.size(), rects, rects + count); rects_.insert(rects_.begin() + rects_.size(), rects, rects + count);
} }
...@@ -165,8 +165,7 @@ class DecoderTester { ...@@ -165,8 +165,7 @@ class DecoderTester {
// Test the content of the update rect. // Test the content of the update rect.
ASSERT_EQ(rects_.size(), update_rects_.size()); ASSERT_EQ(rects_.size(), update_rects_.size());
for (size_t i = 0; i < update_rects_.size(); ++i) { for (size_t i = 0; i < update_rects_.size(); ++i) {
SkIRect &r = rects_[i]; gfx::Rect rect = rects_[i];
gfx::Rect rect(r.fLeft, r.fTop, r.width(), r.height());
EXPECT_EQ(rect, update_rects_[i]); EXPECT_EQ(rect, update_rects_[i]);
EXPECT_EQ(frame_->stride(0), capture_data_->data_planes().strides[0]); EXPECT_EQ(frame_->stride(0), capture_data_->data_planes().strides[0]);
...@@ -187,7 +186,7 @@ class DecoderTester { ...@@ -187,7 +186,7 @@ class DecoderTester {
private: private:
bool strict_; bool strict_;
std::deque<SkIRect> rects_; std::deque<gfx::Rect> rects_;
UpdatedRects update_rects_; UpdatedRects update_rects_;
Decoder* decoder_; Decoder* decoder_;
scoped_refptr<media::VideoFrame> frame_; scoped_refptr<media::VideoFrame> frame_;
...@@ -222,7 +221,7 @@ class EncoderTester { ...@@ -222,7 +221,7 @@ class EncoderTester {
delete packet; delete packet;
} }
void AddRects(const SkIRect* rects, int count) { void AddRects(const gfx::Rect* rects, int count) {
message_tester_->AddRects(rects, count); message_tester_->AddRects(rects, count);
} }
...@@ -264,10 +263,10 @@ scoped_refptr<CaptureData> PrepareEncodeData(media::VideoFrame::Format format, ...@@ -264,10 +263,10 @@ scoped_refptr<CaptureData> PrepareEncodeData(media::VideoFrame::Format format,
static void TestEncodingRects(Encoder* encoder, static void TestEncodingRects(Encoder* encoder,
EncoderTester* tester, EncoderTester* tester,
scoped_refptr<CaptureData> data, scoped_refptr<CaptureData> data,
const SkIRect* rects, int count) { const gfx::Rect* rects, int count) {
data->mutable_dirty_region().setEmpty(); data->mutable_dirty_rects().clear();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
data->mutable_dirty_region().op(rects[i], SkRegion::kUnion_Op); data->mutable_dirty_rects().insert(rects[i]);
} }
tester->AddRects(rects, count); tester->AddRects(rects, count);
...@@ -284,22 +283,22 @@ void TestEncoder(Encoder* encoder, bool strict) { ...@@ -284,22 +283,22 @@ void TestEncoder(Encoder* encoder, bool strict) {
uint8* memory; uint8* memory;
scoped_refptr<CaptureData> data = scoped_refptr<CaptureData> data =
PrepareEncodeData(media::VideoFrame::RGB32, &memory); PrepareEncodeData(media::VideoFrame::RGB32, &memory);
scoped_array<uint8> memory_wrapper(memory);
TestEncodingRects(encoder, &tester, data, kTestRects, 1); TestEncodingRects(encoder, &tester, data, kTestRects, 1);
TestEncodingRects(encoder, &tester, data, kTestRects + 1, 1); TestEncodingRects(encoder, &tester, data, kTestRects + 1, 1);
TestEncodingRects(encoder, &tester, data, kTestRects + 2, 1); TestEncodingRects(encoder, &tester, data, kTestRects + 2, 1);
TestEncodingRects(encoder, &tester, data, kTestRects + 3, 2); TestEncodingRects(encoder, &tester, data, kTestRects + 3, 2);
delete [] memory;
} }
static void TestEncodingRects(Encoder* encoder, static void TestEncodingRects(Encoder* encoder,
EncoderTester* encoder_tester, EncoderTester* encoder_tester,
DecoderTester* decoder_tester, DecoderTester* decoder_tester,
scoped_refptr<CaptureData> data, scoped_refptr<CaptureData> data,
const SkIRect* rects, int count) { const gfx::Rect* rects, int count) {
data->mutable_dirty_region().setEmpty(); data->mutable_dirty_rects().clear();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
data->mutable_dirty_region().op(rects[i], SkRegion::kUnion_Op); data->mutable_dirty_rects().insert(rects[i]);
} }
encoder_tester->AddRects(rects, count); encoder_tester->AddRects(rects, count);
decoder_tester->AddRects(rects, count); decoder_tester->AddRects(rects, count);
...@@ -307,12 +306,12 @@ static void TestEncodingRects(Encoder* encoder, ...@@ -307,12 +306,12 @@ static void TestEncodingRects(Encoder* encoder,
// Generate random data for the updated rects. // Generate random data for the updated rects.
srand(0); srand(0);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
const SkIRect& rect = rects[i]; const gfx::Rect rect = rects[i];
const int bytes_per_pixel = GetBytesPerPixel(data->pixel_format()); const int bytes_per_pixel = GetBytesPerPixel(data->pixel_format());
const int row_size = bytes_per_pixel * rect.width(); const int row_size = bytes_per_pixel * rect.width();
uint8* memory = data->data_planes().data[0] + uint8* memory = data->data_planes().data[0] +
data->data_planes().strides[0] * rect.fTop + data->data_planes().strides[0] * rect.y() +
bytes_per_pixel * rect.fLeft; bytes_per_pixel * rect.x();
for (int y = 0; y < rect.height(); ++y) { for (int y = 0; y < rect.height(); ++y) {
for (int x = 0; x < row_size; ++x) for (int x = 0; x < row_size; ++x)
memory[x] = rand() % 256; memory[x] = rand() % 256;
...@@ -335,8 +334,6 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) { ...@@ -335,8 +334,6 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) {
uint8* memory; uint8* memory;
scoped_refptr<CaptureData> data = scoped_refptr<CaptureData> data =
PrepareEncodeData(media::VideoFrame::RGB32, &memory); PrepareEncodeData(media::VideoFrame::RGB32, &memory);
scoped_array<uint8> memory_wrapper(memory);
DecoderTester decoder_tester(decoder); DecoderTester decoder_tester(decoder);
decoder_tester.set_strict(strict); decoder_tester.set_strict(strict);
decoder_tester.set_capture_data(data); decoder_tester.set_capture_data(data);
...@@ -350,6 +347,7 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) { ...@@ -350,6 +347,7 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) {
kTestRects + 2, 1); kTestRects + 2, 1);
TestEncodingRects(encoder, &encoder_tester, &decoder_tester, data, TestEncodingRects(encoder, &encoder_tester, &decoder_tester, data,
kTestRects + 3, 2); kTestRects + 3, 2);
delete [] memory;
} }
} // namespace remoting } // namespace remoting
......
...@@ -46,8 +46,6 @@ class Decoder { ...@@ -46,8 +46,6 @@ class Decoder {
// Returns rects that were updated in the last frame. Can be called only // Returns rects that were updated in the last frame. Can be called only
// after DecodePacket returned DECODE_DONE. Caller keeps ownership of // after DecodePacket returned DECODE_DONE. Caller keeps ownership of
// |rects|. |rects| is kept empty if whole screen needs to be updated. // |rects|. |rects| is kept empty if whole screen needs to be updated.
// TODO(dmaclach): Move this over to using SkRegion.
// http://crbug.com/92085
virtual void GetUpdatedRects(UpdatedRects* rects) = 0; virtual void GetUpdatedRects(UpdatedRects* rects) = 0;
// Reset the decoder to an uninitialized state. Release all references to // Reset the decoder to an uninitialized state. Release all references to
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -66,19 +66,16 @@ void EncoderRowBased::Encode(scoped_refptr<CaptureData> capture_data, ...@@ -66,19 +66,16 @@ void EncoderRowBased::Encode(scoped_refptr<CaptureData> capture_data,
capture_data_ = capture_data; capture_data_ = capture_data;
callback_.reset(data_available_callback); callback_.reset(data_available_callback);
const SkRegion& region = capture_data->dirty_region(); const InvalidRects& rects = capture_data->dirty_rects();
SkRegion::Iterator iter(region); for (InvalidRects::const_iterator r = rects.begin(); r != rects.end(); ++r) {
while (!iter.done()) { EncodeRect(*r, r == --rects.end());
SkIRect rect = iter.rect();
iter.next();
EncodeRect(rect, iter.done());
} }
capture_data_ = NULL; capture_data_ = NULL;
callback_.reset(); callback_.reset();
} }
void EncoderRowBased::EncodeRect(const SkIRect& rect, bool last) { void EncoderRowBased::EncodeRect(const gfx::Rect& rect, bool last) {
CHECK(capture_data_->data_planes().data[0]); CHECK(capture_data_->data_planes().data[0]);
const int strides = capture_data_->data_planes().strides[0]; const int strides = capture_data_->data_planes().strides[0];
const int bytes_per_pixel = GetBytesPerPixel(capture_data_->pixel_format()); const int bytes_per_pixel = GetBytesPerPixel(capture_data_->pixel_format());
...@@ -89,7 +86,7 @@ void EncoderRowBased::EncodeRect(const SkIRect& rect, bool last) { ...@@ -89,7 +86,7 @@ void EncoderRowBased::EncodeRect(const SkIRect& rect, bool last) {
VideoPacket* packet = new VideoPacket(); VideoPacket* packet = new VideoPacket();
PrepareUpdateStart(rect, packet); PrepareUpdateStart(rect, packet);
const uint8* in = capture_data_->data_planes().data[0] + const uint8* in = capture_data_->data_planes().data[0] +
rect.fTop * strides + rect.fLeft * bytes_per_pixel; rect.y() * strides + rect.x() * bytes_per_pixel;
// TODO(hclam): Fill in the sequence number. // TODO(hclam): Fill in the sequence number.
uint8* out = GetOutputBuffer(packet, packet_size_); uint8* out = GetOutputBuffer(packet, packet_size_);
int filled = 0; int filled = 0;
...@@ -145,13 +142,13 @@ void EncoderRowBased::EncodeRect(const SkIRect& rect, bool last) { ...@@ -145,13 +142,13 @@ void EncoderRowBased::EncodeRect(const SkIRect& rect, bool last) {
} }
} }
void EncoderRowBased::PrepareUpdateStart(const SkIRect& rect, void EncoderRowBased::PrepareUpdateStart(const gfx::Rect& rect,
VideoPacket* packet) { VideoPacket* packet) {
packet->set_flags(packet->flags() | VideoPacket::FIRST_PACKET); packet->set_flags(packet->flags() | VideoPacket::FIRST_PACKET);
VideoPacketFormat* format = packet->mutable_format(); VideoPacketFormat* format = packet->mutable_format();
format->set_x(rect.fLeft); format->set_x(rect.x());
format->set_y(rect.fTop); format->set_y(rect.y());
format->set_width(rect.width()); format->set_width(rect.width());
format->set_height(rect.height()); format->set_height(rect.height());
format->set_encoding(encoding_); format->set_encoding(encoding_);
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
#include "remoting/base/encoder.h" #include "remoting/base/encoder.h"
#include "remoting/proto/video.pb.h" #include "remoting/proto/video.pb.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/gfx/size.h" #include "ui/gfx/rect.h"
namespace remoting { namespace remoting {
...@@ -41,10 +41,10 @@ class EncoderRowBased : public Encoder { ...@@ -41,10 +41,10 @@ class EncoderRowBased : public Encoder {
int packet_size); int packet_size);
// Encode a single dirty rect using compressor. // Encode a single dirty rect using compressor.
void EncodeRect(const SkIRect& rect, bool last); void EncodeRect(const gfx::Rect& rect, bool last);
// Marks a packet as the first in a series of rectangle updates. // Marks a packet as the first in a series of rectangle updates.
void PrepareUpdateStart(const SkIRect& rect, VideoPacket* packet); void PrepareUpdateStart(const gfx::Rect& rect, VideoPacket* packet);
// Retrieves a pointer to the output buffer in |update| used for storing the // Retrieves a pointer to the output buffer in |update| used for storing the
// encoded rectangle data. Will resize the buffer to |size|. // encoded rectangle data. Will resize the buffer to |size|.
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "remoting/base/capture_data.h" #include "remoting/base/capture_data.h"
#include "remoting/base/util.h" #include "remoting/base/util.h"
#include "remoting/proto/video.pb.h" #include "remoting/proto/video.pb.h"
#include "third_party/skia/include/core/SkRegion.h"
extern "C" { extern "C" {
#define VPX_CODEC_DISABLE_COMPAT 1 #define VPX_CODEC_DISABLE_COMPAT 1
...@@ -149,7 +148,7 @@ bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data, ...@@ -149,7 +148,7 @@ bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data,
return false; return false;
} }
const SkRegion& region = capture_data->dirty_region(); const InvalidRects& rects = capture_data->dirty_rects();
const uint8* in = capture_data->data_planes().data[0]; const uint8* in = capture_data->data_planes().data[0];
const int in_stride = capture_data->data_planes().strides[0]; const int in_stride = capture_data->data_planes().strides[0];
const int plane_size = const int plane_size =
...@@ -161,11 +160,9 @@ bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data, ...@@ -161,11 +160,9 @@ bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data,
const int uv_stride = image_->stride[1]; const int uv_stride = image_->stride[1];
DCHECK(updated_rects->empty()); DCHECK(updated_rects->empty());
for (SkRegion::Iterator r(region); !r.done(); r.next()) { for (InvalidRects::const_iterator r = rects.begin(); r != rects.end(); ++r) {
// Align the rectangle, report it as updated. // Align the rectangle, report it as updated.
SkIRect skRect = r.rect(); gfx::Rect rect = AlignAndClipRect(*r, image_->w, image_->h);
gfx::Rect rect(skRect.fLeft, skRect.fTop, skRect.width(), skRect.height());
rect = AlignAndClipRect(rect, image_->w, image_->h);
if (!rect.IsEmpty()) if (!rect.IsEmpty())
updated_rects->push_back(rect); updated_rects->push_back(rect);
......
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_BASE_TYPES_H_
#define REMOTING_BASE_TYPES_H_
#include <set>
#include "ui/gfx/rect.h"
namespace remoting {
// The collection of 'invalid' screen rectangles.
// This is used to keep track of regions of the screen that require
// updating.
typedef std::set<gfx::Rect> InvalidRects;
} // namespace remoting
#endif // REMOTING_BASE_TYPES_H_
...@@ -161,11 +161,11 @@ void CopyRect(const uint8* src_plane, ...@@ -161,11 +161,11 @@ void CopyRect(const uint8* src_plane,
uint8* dest_plane, uint8* dest_plane,
int dest_plane_stride, int dest_plane_stride,
int bytes_per_pixel, int bytes_per_pixel,
const SkIRect& rect) { const gfx::Rect& rect) {
// Get the address of the starting point. // Get the address of the starting point.
const int src_y_offset = src_plane_stride * rect.fTop; const int src_y_offset = src_plane_stride * rect.y();
const int dest_y_offset = dest_plane_stride * rect.fTop; const int dest_y_offset = dest_plane_stride * rect.y();
const int x_offset = bytes_per_pixel * rect.fLeft; const int x_offset = bytes_per_pixel * rect.x();
src_plane += src_y_offset + x_offset; src_plane += src_y_offset + x_offset;
dest_plane += dest_y_offset + x_offset; dest_plane += dest_y_offset + x_offset;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define REMOTING_BASE_UTIL_H_ #define REMOTING_BASE_UTIL_H_
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
namespace remoting { namespace remoting {
...@@ -65,7 +64,7 @@ void CopyRect(const uint8* src_plane, ...@@ -65,7 +64,7 @@ void CopyRect(const uint8* src_plane,
uint8* dest_plane, uint8* dest_plane,
int dest_plane_stride, int dest_plane_stride,
int bytes_per_pixel, int bytes_per_pixel,
const SkIRect& rect); const gfx::Rect& rect);
} // namespace remoting } // namespace remoting
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback_old.h" #include "base/callback_old.h"
#include "remoting/base/capture_data.h" #include "remoting/base/capture_data.h"
#include "third_party/skia/include/core/SkRegion.h" #include "remoting/base/types.h"
namespace remoting { namespace remoting {
...@@ -51,11 +51,11 @@ class Capturer { ...@@ -51,11 +51,11 @@ class Capturer {
// Return the pixel format of the screen. // Return the pixel format of the screen.
virtual media::VideoFrame::Format pixel_format() const = 0; virtual media::VideoFrame::Format pixel_format() const = 0;
// Clear out the invalid region. // Clear out the list of invalid rects.
virtual void ClearInvalidRegion() = 0; virtual void ClearInvalidRects() = 0;
// Invalidate the specified region. // Invalidate the specified screen rects.
virtual void InvalidateRegion(const SkRegion& invalid_region) = 0; virtual void InvalidateRects(const InvalidRects& inval_rects) = 0;
// Invalidate the entire screen, of a given size. // Invalidate the entire screen, of a given size.
virtual void InvalidateScreen(const gfx::Size& size) = 0; virtual void InvalidateScreen(const gfx::Size& size) = 0;
...@@ -65,15 +65,19 @@ class Capturer { ...@@ -65,15 +65,19 @@ class Capturer {
virtual void InvalidateFullScreen() = 0; virtual void InvalidateFullScreen() = 0;
// Capture the screen data associated with each of the accumulated // Capture the screen data associated with each of the accumulated
// dirty region. // rects in |inval_rects|.
// When the capture is complete, |callback| is called even if the dirty region // This routine will first call CalculateInvalidRects to update the
// is empty. // list of |inval_rects|.
// When the capture is complete, |callback| is called.
//
// If |inval_rects_| is empty, then this does nothing except
// call the |callback| routine.
// //
// It is OK to call this method while another thread is reading // It is OK to call this method while another thread is reading
// data of the previous capture. // data of the last capture.
// There can be at most one concurrent read going on when this // There can be at most one concurrent read going on when this
// method is called. // method is called.
virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) = 0; virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) = 0;
// Get the size of the most recently captured screen. // Get the size of the most recently captured screen.
virtual const gfx::Size& size_most_recent() const = 0; virtual const gfx::Size& size_most_recent() const = 0;
......
...@@ -54,12 +54,12 @@ media::VideoFrame::Format CapturerFake::pixel_format() const { ...@@ -54,12 +54,12 @@ media::VideoFrame::Format CapturerFake::pixel_format() const {
return pixel_format_; return pixel_format_;
} }
void CapturerFake::ClearInvalidRegion() { void CapturerFake::ClearInvalidRects() {
helper.ClearInvalidRegion(); helper.ClearInvalidRects();
} }
void CapturerFake::InvalidateRegion(const SkRegion& invalid_region) { void CapturerFake::InvalidateRects(const InvalidRects& inval_rects) {
helper.InvalidateRegion(invalid_region); helper.InvalidateRects(inval_rects);
} }
void CapturerFake::InvalidateScreen(const gfx::Size& size) { void CapturerFake::InvalidateScreen(const gfx::Size& size) {
...@@ -70,14 +70,14 @@ void CapturerFake::InvalidateFullScreen() { ...@@ -70,14 +70,14 @@ void CapturerFake::InvalidateFullScreen() {
helper.InvalidateFullScreen(); helper.InvalidateFullScreen();
} }
void CapturerFake::CaptureInvalidRegion(CaptureCompletedCallback* callback) { void CapturerFake::CaptureInvalidRects(CaptureCompletedCallback* callback) {
scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
GenerateImage(); GenerateImage();
InvalidateScreen(size_); InvalidateScreen(size_);
SkRegion invalid_region; InvalidRects inval_rects;
helper.SwapInvalidRegion(&invalid_region); helper.SwapInvalidRects(inval_rects);
DataPlanes planes; DataPlanes planes;
planes.data[0] = buffers_[current_buffer_].get(); planes.data[0] = buffers_[current_buffer_].get();
...@@ -87,7 +87,7 @@ void CapturerFake::CaptureInvalidRegion(CaptureCompletedCallback* callback) { ...@@ -87,7 +87,7 @@ void CapturerFake::CaptureInvalidRegion(CaptureCompletedCallback* callback) {
scoped_refptr<CaptureData> capture_data(new CaptureData(planes, scoped_refptr<CaptureData> capture_data(new CaptureData(planes,
size_, size_,
pixel_format_)); pixel_format_));
capture_data->mutable_dirty_region() = invalid_region; capture_data->mutable_dirty_rects() = inval_rects;
helper.set_size_most_recent(capture_data->size()); helper.set_size_most_recent(capture_data->size());
......
...@@ -21,15 +21,14 @@ class CapturerFake : public Capturer { ...@@ -21,15 +21,14 @@ class CapturerFake : public Capturer {
virtual ~CapturerFake(); virtual ~CapturerFake();
// Capturer interface. // Capturer interface.
virtual void ScreenConfigurationChanged() OVERRIDE; virtual void ScreenConfigurationChanged();
virtual media::VideoFrame::Format pixel_format() const OVERRIDE; virtual media::VideoFrame::Format pixel_format() const;
virtual void ClearInvalidRegion() OVERRIDE; virtual void ClearInvalidRects();
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; virtual void InvalidateRects(const InvalidRects& inval_rects);
virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; virtual void InvalidateScreen(const gfx::Size& size);
virtual void InvalidateFullScreen() OVERRIDE; virtual void InvalidateFullScreen();
virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
OVERRIDE; virtual const gfx::Size& size_most_recent() const;
virtual const gfx::Size& size_most_recent() const OVERRIDE;
private: private:
// Generates an image in the front buffer. // Generates an image in the front buffer.
......
...@@ -37,23 +37,23 @@ media::VideoFrame::Format CapturerFakeAscii::pixel_format() const { ...@@ -37,23 +37,23 @@ media::VideoFrame::Format CapturerFakeAscii::pixel_format() const {
return pixel_format_; return pixel_format_;
} }
void CapturerFakeAscii::ClearInvalidRegion() { void CapturerFakeAscii::ClearInvalidRects() {
helper_.ClearInvalidRegion(); helper.ClearInvalidRects();
} }
void CapturerFakeAscii::InvalidateRegion(const SkRegion& invalid_region) { void CapturerFakeAscii::InvalidateRects(const InvalidRects& inval_rects) {
helper_.InvalidateRegion(invalid_region); helper.InvalidateRects(inval_rects);
} }
void CapturerFakeAscii::InvalidateScreen(const gfx::Size& size) { void CapturerFakeAscii::InvalidateScreen(const gfx::Size& size) {
helper_.InvalidateScreen(size); helper.InvalidateScreen(size);
} }
void CapturerFakeAscii::InvalidateFullScreen() { void CapturerFakeAscii::InvalidateFullScreen() {
helper_.InvalidateFullScreen(); helper.InvalidateFullScreen();
} }
void CapturerFakeAscii::CaptureInvalidRegion( void CapturerFakeAscii::CaptureInvalidRects(
CaptureCompletedCallback* callback) { CaptureCompletedCallback* callback) {
scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
...@@ -65,13 +65,13 @@ void CapturerFakeAscii::CaptureInvalidRegion( ...@@ -65,13 +65,13 @@ void CapturerFakeAscii::CaptureInvalidRegion(
scoped_refptr<CaptureData> capture_data(new CaptureData( scoped_refptr<CaptureData> capture_data(new CaptureData(
planes, gfx::Size(width_, height_), pixel_format_)); planes, gfx::Size(width_, height_), pixel_format_));
helper_.set_size_most_recent(capture_data->size()); helper.set_size_most_recent(capture_data->size());
callback->Run(capture_data); callback->Run(capture_data);
} }
const gfx::Size& CapturerFakeAscii::size_most_recent() const { const gfx::Size& CapturerFakeAscii::size_most_recent() const {
return helper_.size_most_recent(); return helper.size_most_recent();
} }
void CapturerFakeAscii::GenerateImage() { void CapturerFakeAscii::GenerateImage() {
......
...@@ -22,14 +22,13 @@ class CapturerFakeAscii : public Capturer { ...@@ -22,14 +22,13 @@ class CapturerFakeAscii : public Capturer {
virtual ~CapturerFakeAscii(); virtual ~CapturerFakeAscii();
// Capturer interface. // Capturer interface.
virtual void ScreenConfigurationChanged() OVERRIDE; virtual void ScreenConfigurationChanged();
virtual media::VideoFrame::Format pixel_format() const OVERRIDE; virtual media::VideoFrame::Format pixel_format() const;
virtual void ClearInvalidRegion() OVERRIDE; virtual void ClearInvalidRects();
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; virtual void InvalidateRects(const InvalidRects& inval_rects);
virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; virtual void InvalidateScreen(const gfx::Size& size);
virtual void InvalidateFullScreen() OVERRIDE; virtual void InvalidateFullScreen();
virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
OVERRIDE;
virtual const gfx::Size& size_most_recent() const; virtual const gfx::Size& size_most_recent() const;
private: private:
...@@ -41,7 +40,7 @@ class CapturerFakeAscii : public Capturer { ...@@ -41,7 +40,7 @@ class CapturerFakeAscii : public Capturer {
int height_; int height_;
int bytes_per_row_; int bytes_per_row_;
CapturerHelper helper_; CapturerHelper helper;
// We have two buffers for the screen images as required by Capturer. // We have two buffers for the screen images as required by Capturer.
static const int kNumBuffers = 2; static const int kNumBuffers = 2;
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include "remoting/host/capturer_helper.h" #include "remoting/host/capturer_helper.h"
#include <algorithm>
#include <iterator>
namespace remoting { namespace remoting {
CapturerHelper::CapturerHelper() : size_most_recent_(0, 0) { CapturerHelper::CapturerHelper() : size_most_recent_(0, 0) {
...@@ -12,20 +15,24 @@ CapturerHelper::CapturerHelper() : size_most_recent_(0, 0) { ...@@ -12,20 +15,24 @@ CapturerHelper::CapturerHelper() : size_most_recent_(0, 0) {
CapturerHelper::~CapturerHelper() { CapturerHelper::~CapturerHelper() {
} }
void CapturerHelper::ClearInvalidRegion() { void CapturerHelper::ClearInvalidRects() {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_); base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
invalid_region_.setEmpty(); inval_rects_.clear();
} }
void CapturerHelper::InvalidateRegion(const SkRegion& invalid_region) { void CapturerHelper::InvalidateRects(const InvalidRects& inval_rects) {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_); base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
invalid_region_.op(invalid_region, SkRegion::kUnion_Op); InvalidRects temp_rects;
std::set_union(inval_rects_.begin(), inval_rects_.end(),
inval_rects.begin(), inval_rects.end(),
std::inserter(temp_rects, temp_rects.begin()));
inval_rects_.swap(temp_rects);
} }
void CapturerHelper::InvalidateScreen(const gfx::Size& size) { void CapturerHelper::InvalidateScreen(const gfx::Size& size) {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_); base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
invalid_region_.op(SkIRect::MakeWH(size.width(), size.height()), inval_rects_.clear();
SkRegion::kUnion_Op); inval_rects_.insert(gfx::Rect(0, 0, size.width(), size.height()));
} }
void CapturerHelper::InvalidateFullScreen() { void CapturerHelper::InvalidateFullScreen() {
...@@ -33,17 +40,17 @@ void CapturerHelper::InvalidateFullScreen() { ...@@ -33,17 +40,17 @@ void CapturerHelper::InvalidateFullScreen() {
InvalidateScreen(size_most_recent_); InvalidateScreen(size_most_recent_);
} }
// TODO: Is this actually required?
// http://crbug.com/92346
bool CapturerHelper::IsCaptureFullScreen(const gfx::Size& size) { bool CapturerHelper::IsCaptureFullScreen(const gfx::Size& size) {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_); base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
SkRegion fullScreenRegion(SkIRect::MakeWH(size.width(), size.height())); return inval_rects_.size() == 1u &&
return fullScreenRegion == invalid_region_; inval_rects_.begin()->x() == 0 && inval_rects_.begin()->y() == 0 &&
inval_rects_.begin()->width() == size.width() &&
inval_rects_.begin()->height() == size.height();
} }
void CapturerHelper::SwapInvalidRegion(SkRegion* invalid_region) { void CapturerHelper::SwapInvalidRects(InvalidRects& inval_rects) {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_); base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
invalid_region->swap(invalid_region_); inval_rects.swap(inval_rects_);
} }
const gfx::Size& CapturerHelper::size_most_recent() const { const gfx::Size& CapturerHelper::size_most_recent() const {
......
...@@ -6,24 +6,24 @@ ...@@ -6,24 +6,24 @@
#define REMOTING_HOST_CAPTURER_HELPER_H_ #define REMOTING_HOST_CAPTURER_HELPER_H_
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "third_party/skia/include/core/SkRegion.h" #include "remoting/base/types.h"
#include "ui/gfx/size.h"
namespace remoting { namespace remoting {
// CapturerHelper is intended to be used by an implementation of the Capturer // CapturerHelper is intended to be used by an implementation of the Capturer
// interface. It maintains a thread-safe invalid region, and the size of the // interface. It maintains a thread-safe list of invalid rectangles, and the
// most recently captured screen, on behalf of the Capturer that owns it. // size of the most recently captured screen, on behalf of the Capturer that
// owns it.
class CapturerHelper { class CapturerHelper {
public: public:
CapturerHelper(); CapturerHelper();
~CapturerHelper(); ~CapturerHelper();
// Clear out the invalid region. // Clear out the list of invalid rects.
void ClearInvalidRegion(); void ClearInvalidRects();
// Invalidate the specified region. // Invalidate the specified screen rects.
void InvalidateRegion(const SkRegion& invalid_region); void InvalidateRects(const InvalidRects& inval_rects);
// Invalidate the entire screen, of a given size. // Invalidate the entire screen, of a given size.
void InvalidateScreen(const gfx::Size& size); void InvalidateScreen(const gfx::Size& size);
...@@ -35,21 +35,29 @@ class CapturerHelper { ...@@ -35,21 +35,29 @@ class CapturerHelper {
// Whether the invalid region is a full screen of a given size. // Whether the invalid region is a full screen of a given size.
bool IsCaptureFullScreen(const gfx::Size& size); bool IsCaptureFullScreen(const gfx::Size& size);
// Swap the given region with the stored invalid region. // Swap the given set of rects with the stored invalid rects.
void SwapInvalidRegion(SkRegion* invalid_region); // This should be used like this:
//
// InvalidRects inval_rects;
// common.SwapInvalidRects(inval_rects);
//
// This passes the invalid rects to the caller, and removes them from this
// object. The caller should then pass the raster data in those rects to the
// client.
void SwapInvalidRects(InvalidRects& inval_rects);
// Access the size of the most recently captured screen. // Access the size of the most recently captured screen.
const gfx::Size& size_most_recent() const; const gfx::Size& size_most_recent() const;
void set_size_most_recent(const gfx::Size& size); void set_size_most_recent(const gfx::Size& size);
private: private:
// A region that has been manually invalidated (through InvalidateRegion). // Rects that have been manually invalidated (through InvalidateRect).
// These will be returned as dirty_region in the capture data during the next // These will be returned as dirty_rects in the capture data during the next
// capture. // capture.
SkRegion invalid_region_; InvalidRects inval_rects_;
// A lock protecting |invalid_region_| across threads. // A lock protecting |inval_rects_| across threads.
base::Lock invalid_region_lock_; base::Lock inval_rects_lock_;
// The size of the most recently captured screen. // The size of the most recently captured screen.
gfx::Size size_most_recent_; gfx::Size size_most_recent_;
......
This diff is collapsed.
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "remoting/base/util.h" #include "remoting/base/util.h"
#include "remoting/host/capturer_helper.h" #include "remoting/host/capturer_helper.h"
#include "skia/ext/skia_utils_mac.h"
namespace remoting { namespace remoting {
...@@ -135,20 +134,19 @@ class CapturerMac : public Capturer { ...@@ -135,20 +134,19 @@ class CapturerMac : public Capturer {
// Capturer interface. // Capturer interface.
virtual void ScreenConfigurationChanged() OVERRIDE; virtual void ScreenConfigurationChanged() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE; virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
virtual void ClearInvalidRegion() OVERRIDE; virtual void ClearInvalidRects() OVERRIDE;
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE;
virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
virtual void InvalidateFullScreen() OVERRIDE; virtual void InvalidateFullScreen() OVERRIDE;
virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE;
OVERRIDE;
virtual const gfx::Size& size_most_recent() const OVERRIDE; virtual const gfx::Size& size_most_recent() const OVERRIDE;
private: private:
void GlBlitFast(const VideoFrameBuffer& buffer, const SkRegion& region); void GlBlitFast(const VideoFrameBuffer& buffer, const InvalidRects& rects);
void GlBlitSlow(const VideoFrameBuffer& buffer); void GlBlitSlow(const VideoFrameBuffer& buffer);
void CgBlit(const VideoFrameBuffer& buffer, const SkRegion& region); void CgBlit(const VideoFrameBuffer& buffer, const InvalidRects& rects);
void CaptureRegion(const SkRegion& region, void CaptureRects(const InvalidRects& rects,
CaptureCompletedCallback* callback); CaptureCompletedCallback* callback);
void ScreenRefresh(CGRectCount count, const CGRect *rect_array); void ScreenRefresh(CGRectCount count, const CGRect *rect_array);
void ScreenUpdateMove(CGScreenUpdateMoveDelta delta, void ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
...@@ -178,12 +176,12 @@ class CapturerMac : public Capturer { ...@@ -178,12 +176,12 @@ class CapturerMac : public Capturer {
// The current buffer with valid data for reading. // The current buffer with valid data for reading.
int current_buffer_; int current_buffer_;
// The previous buffer into which we captured, or NULL for the first capture // The last buffer into which we captured, or NULL for the first capture for
// for a particular screen resolution. // a particular screen resolution.
uint8* last_buffer_; uint8* last_buffer_;
// Contains an invalid region from the previous capture. // Contains a list of invalid rectangles in the last capture.
SkRegion last_invalid_region_; InvalidRects last_invalid_rects_;
// Format of pixels returned in buffer. // Format of pixels returned in buffer.
media::VideoFrame::Format pixel_format_; media::VideoFrame::Format pixel_format_;
...@@ -242,7 +240,8 @@ void CapturerMac::ReleaseBuffers() { ...@@ -242,7 +240,8 @@ void CapturerMac::ReleaseBuffers() {
void CapturerMac::ScreenConfigurationChanged() { void CapturerMac::ScreenConfigurationChanged() {
ReleaseBuffers(); ReleaseBuffers();
helper_.ClearInvalidRegion(); InvalidRects rects;
helper_.SwapInvalidRects(rects);
last_buffer_ = NULL; last_buffer_ = NULL;
CGDirectDisplayID mainDevice = CGMainDisplayID(); CGDirectDisplayID mainDevice = CGMainDisplayID();
...@@ -281,12 +280,12 @@ media::VideoFrame::Format CapturerMac::pixel_format() const { ...@@ -281,12 +280,12 @@ media::VideoFrame::Format CapturerMac::pixel_format() const {
return pixel_format_; return pixel_format_;
} }
void CapturerMac::ClearInvalidRegion() { void CapturerMac::ClearInvalidRects() {
helper_.ClearInvalidRegion(); helper_.ClearInvalidRects();
} }
void CapturerMac::InvalidateRegion(const SkRegion& invalid_region) { void CapturerMac::InvalidateRects(const InvalidRects& inval_rects) {
helper_.InvalidateRegion(invalid_region); helper_.InvalidateRects(inval_rects);
} }
void CapturerMac::InvalidateScreen(const gfx::Size& size) { void CapturerMac::InvalidateScreen(const gfx::Size& size) {
...@@ -297,25 +296,25 @@ void CapturerMac::InvalidateFullScreen() { ...@@ -297,25 +296,25 @@ void CapturerMac::InvalidateFullScreen() {
helper_.InvalidateFullScreen(); helper_.InvalidateFullScreen();
} }
void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) { void CapturerMac::CaptureInvalidRects(CaptureCompletedCallback* callback) {
scoped_refptr<CaptureData> data; scoped_refptr<CaptureData> data;
if (capturing_) { if (capturing_) {
SkRegion region; InvalidRects rects;
helper_.SwapInvalidRegion(&region); helper_.SwapInvalidRects(rects);
VideoFrameBuffer& current_buffer = buffers_[current_buffer_]; VideoFrameBuffer& current_buffer = buffers_[current_buffer_];
current_buffer.Update(); current_buffer.Update();
bool flip = true; // GL capturers need flipping. bool flip = true; // GL capturers need flipping.
if (cgl_context_) { if (cgl_context_) {
if (pixel_buffer_object_.get() != 0) { if (pixel_buffer_object_.get() != 0) {
GlBlitFast(current_buffer, region); GlBlitFast(current_buffer, rects);
} else { } else {
// See comment in scoped_pixel_buffer_object::Init about why the slow // See comment in scoped_pixel_buffer_object::Init about why the slow
// path is always used on 10.5. // path is always used on 10.5.
GlBlitSlow(current_buffer); GlBlitSlow(current_buffer);
} }
} else { } else {
CgBlit(current_buffer, region); CgBlit(current_buffer, rects);
flip = false; flip = false;
} }
...@@ -330,7 +329,7 @@ void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) { ...@@ -330,7 +329,7 @@ void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) {
data = new CaptureData(planes, gfx::Size(current_buffer.size()), data = new CaptureData(planes, gfx::Size(current_buffer.size()),
pixel_format()); pixel_format());
data->mutable_dirty_region() = region; data->mutable_dirty_rects() = rects;
current_buffer_ = (current_buffer_ + 1) % kNumBuffers; current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
helper_.set_size_most_recent(data->size()); helper_.set_size_most_recent(data->size());
...@@ -341,28 +340,31 @@ void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) { ...@@ -341,28 +340,31 @@ void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) {
} }
void CapturerMac::GlBlitFast(const VideoFrameBuffer& buffer, void CapturerMac::GlBlitFast(const VideoFrameBuffer& buffer,
const SkRegion& region) { const InvalidRects& rects) {
if (last_buffer_) { if (last_buffer_) {
// We are doing double buffer for the capture data so we just need to copy // We are doing double buffer for the capture data so we just need to copy
// the invalid region from the previous capture in the current buffer. // invalid rects in the last capture in the current buffer.
// TODO(hclam): We can reduce the amount of copying here by subtracting // TODO(hclam): |last_invalid_rects_| and |rects| can overlap and this
// |capturer_helper_|s region from |last_invalid_region_|. // causes extra copies on the overlapped region. Subtract |rects| from
// http://crbug.com/92354 // |last_invalid_rects_| to do a minimal amount of copy when we have proper
// region algorithms implemented.
// Since the image obtained from OpenGL is upside-down, need to do some // Since the image obtained from OpenGL is upside-down, need to do some
// magic here to copy the correct rectangle. // magic here to copy the correct rectangle.
const int y_offset = (buffer.size().height() - 1) * buffer.bytes_per_row(); const int y_offset = (buffer.size().height() - 1) * buffer.bytes_per_row();
for(SkRegion::Iterator i(last_invalid_region_); !i.done(); i.next()) { for (InvalidRects::iterator i = last_invalid_rects_.begin();
i != last_invalid_rects_.end();
++i) {
CopyRect(last_buffer_ + y_offset, CopyRect(last_buffer_ + y_offset,
-buffer.bytes_per_row(), -buffer.bytes_per_row(),
buffer.ptr() + y_offset, buffer.ptr() + y_offset,
-buffer.bytes_per_row(), -buffer.bytes_per_row(),
4, // Bytes for pixel for RGBA. 4, // Bytes for pixel for RGBA.
i.rect()); *i);
} }
} }
last_buffer_ = buffer.ptr(); last_buffer_ = buffer.ptr();
last_invalid_region_ = region; last_invalid_rects_ = rects;
CGLContextObj CGL_MACRO_CONTEXT = cgl_context_; CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_.get()); glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_.get());
...@@ -378,13 +380,13 @@ void CapturerMac::GlBlitFast(const VideoFrameBuffer& buffer, ...@@ -378,13 +380,13 @@ void CapturerMac::GlBlitFast(const VideoFrameBuffer& buffer,
// Copy only from the dirty rects. Since the image obtained from OpenGL is // Copy only from the dirty rects. Since the image obtained from OpenGL is
// upside-down we need to do some magic here to copy the correct rectangle. // upside-down we need to do some magic here to copy the correct rectangle.
const int y_offset = (buffer.size().height() - 1) * buffer.bytes_per_row(); const int y_offset = (buffer.size().height() - 1) * buffer.bytes_per_row();
for(SkRegion::Iterator i(region); !i.done(); i.next()) { for (InvalidRects::iterator i = rects.begin(); i != rects.end(); ++i) {
CopyRect(ptr + y_offset, CopyRect(ptr + y_offset,
-buffer.bytes_per_row(), -buffer.bytes_per_row(),
buffer.ptr() + y_offset, buffer.ptr() + y_offset,
-buffer.bytes_per_row(), -buffer.bytes_per_row(),
4, // Bytes for pixel for RGBA. 4, // Bytes for pixel for RGBA.
i.rect()); *i);
} }
} }
if (!glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB)) { if (!glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB)) {
...@@ -413,7 +415,7 @@ void CapturerMac::GlBlitSlow(const VideoFrameBuffer& buffer) { ...@@ -413,7 +415,7 @@ void CapturerMac::GlBlitSlow(const VideoFrameBuffer& buffer) {
} }
void CapturerMac::CgBlit(const VideoFrameBuffer& buffer, void CapturerMac::CgBlit(const VideoFrameBuffer& buffer,
const SkRegion& region) { const InvalidRects& rects) {
if (last_buffer_) if (last_buffer_)
memcpy(buffer.ptr(), last_buffer_, memcpy(buffer.ptr(), last_buffer_,
buffer.bytes_per_row() * buffer.size().height()); buffer.bytes_per_row() * buffer.size().height());
...@@ -423,16 +425,13 @@ void CapturerMac::CgBlit(const VideoFrameBuffer& buffer, ...@@ -423,16 +425,13 @@ void CapturerMac::CgBlit(const VideoFrameBuffer& buffer,
reinterpret_cast<uint8*>(CGDisplayBaseAddress(main_display)); reinterpret_cast<uint8*>(CGDisplayBaseAddress(main_display));
int src_bytes_per_row = CGDisplayBytesPerRow(main_display); int src_bytes_per_row = CGDisplayBytesPerRow(main_display);
int src_bytes_per_pixel = CGDisplayBitsPerPixel(main_display) / 8; int src_bytes_per_pixel = CGDisplayBitsPerPixel(main_display) / 8;
// TODO(hclam): We can reduce the amount of copying here by subtracting for (InvalidRects::iterator i = rects.begin(); i != rects.end(); ++i) {
// |capturer_helper_|s region from |last_invalid_region_|.
// http://crbug.com/92354
for(SkRegion::Iterator i(region); !i.done(); i.next()) {
CopyRect(display_base_address, CopyRect(display_base_address,
src_bytes_per_row, src_bytes_per_row,
buffer.ptr(), buffer.ptr(),
buffer.bytes_per_row(), buffer.bytes_per_row(),
src_bytes_per_pixel, src_bytes_per_pixel,
i.rect()); *i);
} }
} }
...@@ -441,27 +440,24 @@ const gfx::Size& CapturerMac::size_most_recent() const { ...@@ -441,27 +440,24 @@ const gfx::Size& CapturerMac::size_most_recent() const {
} }
void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) { void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) {
SkIRect skirect_array[count]; InvalidRects rects;
for (CGRectCount i = 0; i < count; ++i) { for (CGRectCount i = 0; i < count; ++i) {
skirect_array[i] = gfx::CGRectToSkIRect(rect_array[i]); rects.insert(gfx::Rect(rect_array[i]));
} }
SkRegion region; InvalidateRects(rects);
region.setRects(skirect_array, count);
InvalidateRegion(region);
} }
void CapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta, void CapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
size_t count, size_t count,
const CGRect *rect_array) { const CGRect *rect_array) {
SkIRect skirect_new_array[count]; InvalidRects rects;
for (CGRectCount i = 0; i < count; ++i) { for (CGRectCount i = 0; i < count; ++i) {
CGRect rect = rect_array[i]; CGRect rect = rect_array[i];
rects.insert(gfx::Rect(rect));
rect = CGRectOffset(rect, delta.dX, delta.dY); rect = CGRectOffset(rect, delta.dX, delta.dY);
skirect_new_array[i] = gfx::CGRectToSkIRect(rect); rects.insert(gfx::Rect(rect));
} }
SkRegion region; InvalidateRects(rects);
region.setRects(skirect_new_array, count);
InvalidateRegion(region);
} }
void CapturerMac::ScreenRefreshCallback(CGRectCount count, void CapturerMac::ScreenRefreshCallback(CGRectCount count,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "remoting/base/types.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace remoting { namespace remoting {
...@@ -21,12 +22,11 @@ class CapturerMacTest : public testing::Test { ...@@ -21,12 +22,11 @@ class CapturerMacTest : public testing::Test {
} }
void AddDirtyRect() { void AddDirtyRect() {
SkIRect rect = SkIRect::MakeXYWH(0, 0, 10, 10); rects_.insert(gfx::Rect(0, 0, 10, 10));
region_.op(rect, SkRegion::kUnion_Op);
} }
scoped_ptr<Capturer> capturer_; scoped_ptr<Capturer> capturer_;
SkRegion region_; InvalidRects rects_;
}; };
// CapturerCallback1 verifies that the whole screen is initially dirty. // CapturerCallback1 verifies that the whole screen is initially dirty.
...@@ -44,20 +44,21 @@ void CapturerCallback1::CaptureDoneCallback( ...@@ -44,20 +44,21 @@ void CapturerCallback1::CaptureDoneCallback(
CGDirectDisplayID mainDevice = CGMainDisplayID(); CGDirectDisplayID mainDevice = CGMainDisplayID();
int width = CGDisplayPixelsWide(mainDevice); int width = CGDisplayPixelsWide(mainDevice);
int height = CGDisplayPixelsHigh(mainDevice); int height = CGDisplayPixelsHigh(mainDevice);
SkRegion initial_region(SkIRect::MakeXYWH(0, 0, width, height)); InvalidRects initial_rect;
EXPECT_EQ(initial_region, capture_data->dirty_region()); initial_rect.insert(gfx::Rect(0, 0, width, height));
EXPECT_EQ(initial_rect, capture_data->dirty_rects());
} }
// CapturerCallback2 verifies that a rectangle explicitly marked as dirty is // CapturerCallback2 verifies that a rectangle explicitly marked as dirty is
// propagated correctly. // propagated correctly.
class CapturerCallback2 { class CapturerCallback2 {
public: public:
explicit CapturerCallback2(const SkRegion& expected_dirty_region) explicit CapturerCallback2(const InvalidRects& expected_dirty_rects)
: expected_dirty_region_(expected_dirty_region) { } : expected_dirty_rects_(expected_dirty_rects) { }
void CaptureDoneCallback(scoped_refptr<CaptureData> capture_data); void CaptureDoneCallback(scoped_refptr<CaptureData> capture_data);
protected: protected:
SkRegion expected_dirty_region_; InvalidRects expected_dirty_rects_;
private: private:
DISALLOW_COPY_AND_ASSIGN(CapturerCallback2); DISALLOW_COPY_AND_ASSIGN(CapturerCallback2);
...@@ -69,7 +70,7 @@ void CapturerCallback2::CaptureDoneCallback( ...@@ -69,7 +70,7 @@ void CapturerCallback2::CaptureDoneCallback(
int width = CGDisplayPixelsWide(mainDevice); int width = CGDisplayPixelsWide(mainDevice);
int height = CGDisplayPixelsHigh(mainDevice); int height = CGDisplayPixelsHigh(mainDevice);
EXPECT_EQ(expected_dirty_region_, capture_data->dirty_region()); EXPECT_EQ(expected_dirty_rects_, capture_data->dirty_rects());
EXPECT_EQ(width, capture_data->size().width()); EXPECT_EQ(width, capture_data->size().width());
EXPECT_EQ(height, capture_data->size().height()); EXPECT_EQ(height, capture_data->size().height());
const DataPlanes &planes = capture_data->data_planes(); const DataPlanes &planes = capture_data->data_planes();
...@@ -88,13 +89,13 @@ TEST_F(CapturerMacTest, Capture) { ...@@ -88,13 +89,13 @@ TEST_F(CapturerMacTest, Capture) {
SCOPED_TRACE(""); SCOPED_TRACE("");
// Check that we get an initial full-screen updated. // Check that we get an initial full-screen updated.
CapturerCallback1 callback1; CapturerCallback1 callback1;
capturer_->CaptureInvalidRegion( capturer_->CaptureInvalidRects(
NewCallback(&callback1, &CapturerCallback1::CaptureDoneCallback)); NewCallback(&callback1, &CapturerCallback1::CaptureDoneCallback));
// Check that subsequent dirty rects are propagated correctly. // Check that subsequent dirty rects are propagated correctly.
AddDirtyRect(); AddDirtyRect();
CapturerCallback2 callback2(region_); CapturerCallback2 callback2(rects_);
capturer_->InvalidateRegion(region_); capturer_->InvalidateRects(rects_);
capturer_->CaptureInvalidRegion( capturer_->CaptureInvalidRects(
NewCallback(&callback2, &CapturerCallback2::CaptureDoneCallback)); NewCallback(&callback2, &CapturerCallback2::CaptureDoneCallback));
} }
...@@ -102,14 +103,13 @@ TEST_F(CapturerMacTest, Capture) { ...@@ -102,14 +103,13 @@ TEST_F(CapturerMacTest, Capture) {
namespace gfx { namespace gfx {
std::ostream& operator<<(std::ostream& out, const SkRegion& region) { std::ostream& operator<<(std::ostream& out,
out << "SkRegion("; const remoting::InvalidRects& rects) {
for (SkRegion::Iterator i(region); !i.done(); i.next()) { for (remoting::InvalidRects::const_iterator i = rects.begin();
const SkIRect& r = i.rect(); i != rects.end();
out << "(" << r.fLeft << "," << r.fTop << "," ++i) {
<< r.fRight << "," << r.fBottom << ")"; out << *i << std::endl;
} }
out << ")";
return out; return out;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "remoting/host/capturer_helper.h" #include "remoting/host/capturer_helper.h"
#include "remoting/host/differ.h" #include "remoting/host/differ.h"
#include "ui/gfx/rect.h"
namespace remoting { namespace remoting {
...@@ -26,12 +27,11 @@ class CapturerGdi : public Capturer { ...@@ -26,12 +27,11 @@ class CapturerGdi : public Capturer {
// Capturer interface. // Capturer interface.
virtual void ScreenConfigurationChanged() OVERRIDE; virtual void ScreenConfigurationChanged() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE; virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
virtual void ClearInvalidRegion() OVERRIDE; virtual void ClearInvalidRects() OVERRIDE;
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE;
virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
virtual void InvalidateFullScreen() OVERRIDE; virtual void InvalidateFullScreen() OVERRIDE;
virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE;
OVERRIDE;
virtual const gfx::Size& size_most_recent() const OVERRIDE; virtual const gfx::Size& size_most_recent() const OVERRIDE;
private: private:
...@@ -60,9 +60,9 @@ class CapturerGdi : public Capturer { ...@@ -60,9 +60,9 @@ class CapturerGdi : public Capturer {
// allocated for that buffer. // allocated for that buffer.
void ReallocateBuffer(int buffer_index, const gfx::Size& size); void ReallocateBuffer(int buffer_index, const gfx::Size& size);
void CalculateInvalidRegion(); void CalculateInvalidRects();
void CaptureRegion(const SkRegion& region, void CaptureRects(const InvalidRects& rects,
CaptureCompletedCallback* callback); CaptureCompletedCallback* callback);
void ReleaseBuffers(); void ReleaseBuffers();
// Generates an image in the current buffer. // Generates an image in the current buffer.
...@@ -77,7 +77,7 @@ class CapturerGdi : public Capturer { ...@@ -77,7 +77,7 @@ class CapturerGdi : public Capturer {
// A thread-safe list of invalid rectangles, and the size of the most // A thread-safe list of invalid rectangles, and the size of the most
// recently captured screen. // recently captured screen.
CapturerHelper helper_; CapturerHelper helper;
// There are two buffers for the screen images, as required by Capturer. // There are two buffers for the screen images, as required by Capturer.
static const int kNumBuffers = 2; static const int kNumBuffers = 2;
...@@ -132,31 +132,31 @@ media::VideoFrame::Format CapturerGdi::pixel_format() const { ...@@ -132,31 +132,31 @@ media::VideoFrame::Format CapturerGdi::pixel_format() const {
return pixel_format_; return pixel_format_;
} }
void CapturerGdi::ClearInvalidRegion() { void CapturerGdi::ClearInvalidRects() {
helper_.ClearInvalidRegion(); helper.ClearInvalidRects();
} }
void CapturerGdi::InvalidateRegion(const SkRegion& invalid_region) { void CapturerGdi::InvalidateRects(const InvalidRects& inval_rects) {
helper_.InvalidateRegion(invalid_region); helper.InvalidateRects(inval_rects);
} }
void CapturerGdi::InvalidateScreen(const gfx::Size& size) { void CapturerGdi::InvalidateScreen(const gfx::Size& size) {
helper_.InvalidateScreen(size); helper.InvalidateScreen(size);
} }
void CapturerGdi::InvalidateFullScreen() { void CapturerGdi::InvalidateFullScreen() {
helper_.InvalidateFullScreen(); helper.InvalidateFullScreen();
} }
void CapturerGdi::CaptureInvalidRegion(CaptureCompletedCallback* callback) { void CapturerGdi::CaptureInvalidRects(CaptureCompletedCallback* callback) {
CalculateInvalidRegion(); CalculateInvalidRects();
SkRegion invalid_region; InvalidRects inval_rects;
helper_.SwapInvalidRegion(&invalid_region); helper.SwapInvalidRects(inval_rects);
CaptureRegion(invalid_region, callback); CaptureRects(inval_rects, callback);
} }
const gfx::Size& CapturerGdi::size_most_recent() const { const gfx::Size& CapturerGdi::size_most_recent() const {
return helper_.size_most_recent(); return helper.size_most_recent();
} }
void CapturerGdi::ReleaseBuffers() { void CapturerGdi::ReleaseBuffers() {
...@@ -243,11 +243,11 @@ void CapturerGdi::ReallocateBuffer(int buffer_index, const gfx::Size& size) { ...@@ -243,11 +243,11 @@ void CapturerGdi::ReallocateBuffer(int buffer_index, const gfx::Size& size) {
bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight); bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight);
} }
void CapturerGdi::CalculateInvalidRegion() { void CapturerGdi::CalculateInvalidRects() {
CaptureImage(); CaptureImage();
const VideoFrameBuffer& current = buffers_[current_buffer_]; const VideoFrameBuffer& current = buffers_[current_buffer_];
if (helper_.IsCaptureFullScreen(current.size)) if (helper.IsCaptureFullScreen(current.size))
capture_fullscreen_ = true; capture_fullscreen_ = true;
if (capture_fullscreen_) { if (capture_fullscreen_) {
...@@ -282,14 +282,14 @@ void CapturerGdi::CalculateInvalidRegion() { ...@@ -282,14 +282,14 @@ void CapturerGdi::CalculateInvalidRegion() {
current.bytes_per_pixel, current.bytes_per_row)); current.bytes_per_pixel, current.bytes_per_row));
} }
SkRegion region; InvalidRects rects;
differ_->CalcDirtyRegion(prev.data, current.data, &region); differ_->CalcDirtyRects(prev.data, current.data, &rects);
InvalidateRegion(region); InvalidateRects(rects);
} }
void CapturerGdi::CaptureRegion(const SkRegion& region, void CapturerGdi::CaptureRects(const InvalidRects& rects,
CaptureCompletedCallback* callback) { CaptureCompletedCallback* callback) {
scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
const VideoFrameBuffer& buffer = buffers_[current_buffer_]; const VideoFrameBuffer& buffer = buffers_[current_buffer_];
...@@ -302,9 +302,9 @@ void CapturerGdi::CaptureRegion(const SkRegion& region, ...@@ -302,9 +302,9 @@ void CapturerGdi::CaptureRegion(const SkRegion& region,
scoped_refptr<CaptureData> data(new CaptureData(planes, scoped_refptr<CaptureData> data(new CaptureData(planes,
buffer.size, buffer.size,
pixel_format_)); pixel_format_));
data->mutable_dirty_region() = region; data->mutable_dirty_rects() = rects;
helper_.set_size_most_recent(data->size()); helper.set_size_most_recent(data->size());
callback->Run(data); callback->Run(data);
} }
......
...@@ -26,12 +26,12 @@ Differ::Differ(int width, int height, int bpp, int stride) { ...@@ -26,12 +26,12 @@ Differ::Differ(int width, int height, int bpp, int stride) {
Differ::~Differ() {} Differ::~Differ() {}
void Differ::CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer, void Differ::CalcDirtyRects(const void* prev_buffer, const void* curr_buffer,
SkRegion* region) { InvalidRects* rects) {
if (!region) { if (!rects) {
return; return;
} }
region->setEmpty(); rects->clear();
if (!prev_buffer || !curr_buffer) { if (!prev_buffer || !curr_buffer) {
return; return;
...@@ -42,7 +42,7 @@ void Differ::CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer, ...@@ -42,7 +42,7 @@ void Differ::CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer,
// Now that we've identified the blocks that have changed, merge adjacent // Now that we've identified the blocks that have changed, merge adjacent
// blocks to minimize the number of rects that we return. // blocks to minimize the number of rects that we return.
MergeBlocks(region); MergeBlocks(rects);
} }
void Differ::MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer) { void Differ::MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer) {
...@@ -131,9 +131,9 @@ DiffInfo Differ::DiffPartialBlock(const uint8* prev_buffer, ...@@ -131,9 +131,9 @@ DiffInfo Differ::DiffPartialBlock(const uint8* prev_buffer,
return 0; return 0;
} }
void Differ::MergeBlocks(SkRegion* region) { void Differ::MergeBlocks(InvalidRects* rects) {
DCHECK(region); DCHECK(rects);
region->setEmpty(); rects->clear();
uint8* diff_info_row_start = static_cast<uint8*>(diff_info_.get()); uint8* diff_info_row_start = static_cast<uint8*>(diff_info_.get());
int diff_info_stride = diff_info_width_ * sizeof(DiffInfo); int diff_info_stride = diff_info_width_ * sizeof(DiffInfo);
...@@ -195,8 +195,7 @@ void Differ::MergeBlocks(SkRegion* region) { ...@@ -195,8 +195,7 @@ void Differ::MergeBlocks(SkRegion* region) {
if (top + height > height_) { if (top + height > height_) {
height = height_ - top; height = height_ - top;
} }
region->op(SkIRect::MakeXYWH(left, top, width, height), rects->insert(gfx::Rect(left, top, width, height));
SkRegion::kUnion_Op);
} }
// Increment to next block in this row. // Increment to next block in this row.
......
...@@ -9,16 +9,13 @@ ...@@ -9,16 +9,13 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkRegion.h" #include "remoting/base/types.h"
#include "ui/gfx/rect.h"
namespace remoting { namespace remoting {
typedef uint8 DiffInfo; typedef uint8 DiffInfo;
// TODO: Simplify differ now that we are working with SkRegions.
// diff_info_ should no longer be needed, as we can put our data directly into
// the region that we are calculating.
// http://crbug.com/92379
class Differ { class Differ {
public: public:
// Create a differ that operates on bitmaps with the specified width, height // Create a differ that operates on bitmaps with the specified width, height
...@@ -31,22 +28,24 @@ class Differ { ...@@ -31,22 +28,24 @@ class Differ {
int bytes_per_pixel() { return bytes_per_pixel_; } int bytes_per_pixel() { return bytes_per_pixel_; }
int bytes_per_row() { return bytes_per_row_; } int bytes_per_row() { return bytes_per_row_; }
// Given the previous and current screen buffer, calculate the dirty region // Given the previous and current screen buffer, calculate the set of
// that encloses all of the changed pixels in the new screen. // rectangles that enclose all the changed pixels in the new screen.
void CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer, void CalcDirtyRects(const void* prev_buffer, const void* curr_buffer,
SkRegion* region); InvalidRects* rects);
private:
// Allow tests to access our private parts.
friend class DifferTest;
// Identify all of the blocks that contain changed pixels. // Identify all of the blocks that contain changed pixels.
void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer); void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer);
// After the dirty blocks have been identified, this routine merges adjacent // After the dirty blocks have been identified, this routine merges adjacent
// blocks into a region. // blocks into larger rectangular units.
// The goal is to minimize the region that covers the dirty blocks. // The goal is to minimize the number of rects that cover the dirty blocks,
void MergeBlocks(SkRegion* region); // although it is not required to calc the absolute minimum of rects.
void MergeBlocks(InvalidRects* rects);
// Allow tests to access our private parts.
friend class DifferTest;
private:
// Check for diffs in upper-left portion of the block. The size of the portion // Check for diffs in upper-left portion of the block. The size of the portion
// to check is specified by the |width| and |height| values. // to check is specified by the |width| and |height| values.
......
This diff is collapsed.
...@@ -26,11 +26,11 @@ class MockCapturer : public Capturer { ...@@ -26,11 +26,11 @@ class MockCapturer : public Capturer {
MOCK_METHOD0(ScreenConfigurationChanged, void()); MOCK_METHOD0(ScreenConfigurationChanged, void());
MOCK_CONST_METHOD0(pixel_format, media::VideoFrame::Format()); MOCK_CONST_METHOD0(pixel_format, media::VideoFrame::Format());
MOCK_METHOD0(ClearInvalidRegion, void()); MOCK_METHOD0(ClearInvalidRects, void());
MOCK_METHOD1(InvalidateRegion, void(const SkRegion& invalid_region)); MOCK_METHOD1(InvalidateRects, void(const InvalidRects& inval_rects));
MOCK_METHOD1(InvalidateScreen, void(const gfx::Size&)); MOCK_METHOD1(InvalidateScreen, void(const gfx::Size&));
MOCK_METHOD0(InvalidateFullScreen, void()); MOCK_METHOD0(InvalidateFullScreen, void());
MOCK_METHOD1(CaptureInvalidRegion, void(CaptureCompletedCallback* callback)); MOCK_METHOD1(CaptureInvalidRects, void(CaptureCompletedCallback* callback));
MOCK_CONST_METHOD0(size_most_recent, const gfx::Size&()); MOCK_CONST_METHOD0(size_most_recent, const gfx::Size&());
private: private:
......
...@@ -218,7 +218,7 @@ void ScreenRecorder::DoCapture() { ...@@ -218,7 +218,7 @@ void ScreenRecorder::DoCapture() {
// And finally perform one capture. // And finally perform one capture.
capture_start_time_ = base::Time::Now(); capture_start_time_ = base::Time::Now();
capturer()->CaptureInvalidRegion( capturer()->CaptureInvalidRects(
NewCallback(this, &ScreenRecorder::CaptureDoneCallback)); NewCallback(this, &ScreenRecorder::CaptureDoneCallback));
} }
...@@ -365,7 +365,7 @@ void ScreenRecorder::DoEncode( ...@@ -365,7 +365,7 @@ void ScreenRecorder::DoEncode(
TraceContext::tracer()->PrintString("DoEncode called"); TraceContext::tracer()->PrintString("DoEncode called");
// Early out if there's nothing to encode. // Early out if there's nothing to encode.
if (!capture_data || capture_data->dirty_region().isEmpty()) { if (!capture_data || !capture_data->dirty_rects().size()) {
// Send an empty video packet to keep network active. // Send an empty video packet to keep network active.
VideoPacket* packet = new VideoPacket(); VideoPacket* packet = new VideoPacket();
packet->set_flags(VideoPacket::LAST_PARTITION); packet->set_flags(VideoPacket::LAST_PARTITION);
......
...@@ -31,9 +31,13 @@ namespace remoting { ...@@ -31,9 +31,13 @@ namespace remoting {
namespace { namespace {
ACTION_P2(RunCallback, region, data) { ACTION_P2(RunCallback, rects, data) {
SkRegion& dirty_region = data->mutable_dirty_region(); InvalidRects& dirty_rects = data->mutable_dirty_rects();
dirty_region.op(region, SkRegion::kUnion_Op); InvalidRects temp_rects;
std::set_union(dirty_rects.begin(), dirty_rects.end(),
rects.begin(), rects.end(),
std::inserter(temp_rects, temp_rects.begin()));
dirty_rects.swap(temp_rects);
arg0->Run(data); arg0->Run(data);
delete arg0; delete arg0;
} }
...@@ -103,7 +107,8 @@ class ScreenRecorderTest : public testing::Test { ...@@ -103,7 +107,8 @@ class ScreenRecorderTest : public testing::Test {
// This test mocks capturer, encoder and network layer to operate one recording // This test mocks capturer, encoder and network layer to operate one recording
// cycle. // cycle.
TEST_F(ScreenRecorderTest, OneRecordCycle) { TEST_F(ScreenRecorderTest, OneRecordCycle) {
SkRegion update_region(SkIRect::MakeXYWH(0, 0, 10, 10)); InvalidRects update_rects;
update_rects.insert(gfx::Rect(0, 0, 10, 10));
DataPlanes planes; DataPlanes planes;
for (int i = 0; i < DataPlanes::kPlaneCount; ++i) { for (int i = 0; i < DataPlanes::kPlaneCount; ++i) {
planes.data[i] = reinterpret_cast<uint8*>(i); planes.data[i] = reinterpret_cast<uint8*>(i);
...@@ -114,8 +119,8 @@ TEST_F(ScreenRecorderTest, OneRecordCycle) { ...@@ -114,8 +119,8 @@ TEST_F(ScreenRecorderTest, OneRecordCycle) {
EXPECT_CALL(capturer_, InvalidateFullScreen()); EXPECT_CALL(capturer_, InvalidateFullScreen());
// First the capturer is called. // First the capturer is called.
EXPECT_CALL(capturer_, CaptureInvalidRegion(NotNull())) EXPECT_CALL(capturer_, CaptureInvalidRects(NotNull()))
.WillOnce(RunCallback(update_region, data)); .WillOnce(RunCallback(update_rects, data));
// Expect the encoder be called. // Expect the encoder be called.
EXPECT_CALL(*encoder_, Encode(data, false, NotNull())) EXPECT_CALL(*encoder_, Encode(data, false, NotNull()))
...@@ -151,7 +156,8 @@ TEST_F(ScreenRecorderTest, OneRecordCycle) { ...@@ -151,7 +156,8 @@ TEST_F(ScreenRecorderTest, OneRecordCycle) {
// ScreenRecorder is instructed to come to a complete stop. We expect the stop // ScreenRecorder is instructed to come to a complete stop. We expect the stop
// sequence to be executed successfully. // sequence to be executed successfully.
TEST_F(ScreenRecorderTest, StartAndStop) { TEST_F(ScreenRecorderTest, StartAndStop) {
SkRegion update_region(SkIRect::MakeXYWH(0, 0, 10, 10)); InvalidRects update_rects;
update_rects.insert(gfx::Rect(0, 0, 10, 10));
DataPlanes planes; DataPlanes planes;
for (int i = 0; i < DataPlanes::kPlaneCount; ++i) { for (int i = 0; i < DataPlanes::kPlaneCount; ++i) {
planes.data[i] = reinterpret_cast<uint8*>(i); planes.data[i] = reinterpret_cast<uint8*>(i);
...@@ -163,8 +169,8 @@ TEST_F(ScreenRecorderTest, StartAndStop) { ...@@ -163,8 +169,8 @@ TEST_F(ScreenRecorderTest, StartAndStop) {
EXPECT_CALL(capturer_, InvalidateFullScreen()); EXPECT_CALL(capturer_, InvalidateFullScreen());
// First the capturer is called. // First the capturer is called.
EXPECT_CALL(capturer_, CaptureInvalidRegion(NotNull())) EXPECT_CALL(capturer_, CaptureInvalidRects(NotNull()))
.WillRepeatedly(RunCallback(update_region, data)); .WillRepeatedly(RunCallback(update_rects, data));
// Expect the encoder be called. // Expect the encoder be called.
EXPECT_CALL(*encoder_, Encode(data, false, NotNull())) EXPECT_CALL(*encoder_, Encode(data, false, NotNull()))
......
...@@ -148,21 +148,21 @@ void XServerPixelBuffer::Synchronize() { ...@@ -148,21 +148,21 @@ void XServerPixelBuffer::Synchronize() {
} }
} }
uint8* XServerPixelBuffer::CaptureRect(const SkIRect& rect) { uint8* XServerPixelBuffer::CaptureRect(const gfx::Rect& rect) {
if (shm_segment_info_) { if (shm_segment_info_) {
if (shm_pixmap_) { if (shm_pixmap_) {
XCopyArea(display_, root_window_, shm_pixmap_, shm_gc_, XCopyArea(display_, root_window_, shm_pixmap_, shm_gc_,
rect.fLeft, rect.fTop, rect.width(), rect.height(), rect.x(), rect.y(), rect.width(), rect.height(),
rect.fLeft, rect.fTop); rect.x(), rect.y());
XSync(display_, False); XSync(display_, False);
} }
return reinterpret_cast<uint8*>(x_image_->data) + return reinterpret_cast<uint8*>(x_image_->data) +
rect.fTop * x_image_->bytes_per_line + rect.y() * x_image_->bytes_per_line +
rect.fLeft * x_image_->bits_per_pixel / 8; rect.x() * x_image_->bits_per_pixel / 8;
} else { } else {
if (x_image_) if (x_image_)
XDestroyImage(x_image_); XDestroyImage(x_image_);
x_image_ = XGetImage(display_, root_window_, rect.fLeft, rect.fTop, x_image_ = XGetImage(display_, root_window_, rect.x(), rect.y(),
rect.width(), rect.height(), AllPlanes, ZPixmap); rect.width(), rect.height(), AllPlanes, ZPixmap);
return reinterpret_cast<uint8*>(x_image_->data); return reinterpret_cast<uint8*>(x_image_->data);
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkRect.h" #include "ui/gfx/rect.h"
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/extensions/XShm.h> #include <X11/extensions/XShm.h>
...@@ -38,7 +38,7 @@ class XServerPixelBuffer { ...@@ -38,7 +38,7 @@ class XServerPixelBuffer {
// call to CaptureRect. // call to CaptureRect.
// In the case where the full-screen data is captured by Synchronize(), this // In the case where the full-screen data is captured by Synchronize(), this
// simply returns the pointer without doing any more work. // simply returns the pointer without doing any more work.
uint8* CaptureRect(const SkIRect& rect); uint8* CaptureRect(const gfx::Rect& rect);
// Return information about the most recent capture. This is only guaranteed // Return information about the most recent capture. This is only guaranteed
// to be valid between CaptureRect calls. // to be valid between CaptureRect calls.
......
...@@ -167,9 +167,6 @@ ...@@ -167,9 +167,6 @@
'remoting_jingle_glue', 'remoting_jingle_glue',
'../third_party/npapi/npapi.gyp:npapi', '../third_party/npapi/npapi.gyp:npapi',
], ],
'include_dirs': [
'../skia/config',
],
'sources': [ 'sources': [
'host/plugin/host_plugin.cc', 'host/plugin/host_plugin.cc',
'host/plugin/host_plugin.def', 'host/plugin/host_plugin.def',
...@@ -181,11 +178,6 @@ ...@@ -181,11 +178,6 @@
'host/plugin/host_script_object.h', 'host/plugin/host_script_object.h',
], ],
'conditions': [ 'conditions': [
['OS=="win"', {
'include_dirs': [
'../third_party/skia/include/config',
],
}],
['OS=="mac"', { ['OS=="mac"', {
'mac_bundle': 1, 'mac_bundle': 1,
'xcode_settings': { 'xcode_settings': {
...@@ -300,9 +292,6 @@ ...@@ -300,9 +292,6 @@
# TODO(hclam): Enable VP8 in the build. # TODO(hclam): Enable VP8 in the build.
#'third_party/on2/on2.gyp:vp8', #'third_party/on2/on2.gyp:vp8',
], ],
'include_dirs': [
'../skia/config',
],
'export_dependent_settings': [ 'export_dependent_settings': [
'../base/base.gyp:base', '../base/base.gyp:base',
'../net/net.gyp:net', '../net/net.gyp:net',
...@@ -349,6 +338,7 @@ ...@@ -349,6 +338,7 @@
'base/task_thread_proxy.h', 'base/task_thread_proxy.h',
'base/tracer.cc', 'base/tracer.cc',
'base/tracer.h', 'base/tracer.h',
'base/types.h',
'base/util.cc', 'base/util.cc',
'base/util.h', 'base/util.h',
], ],
...@@ -361,11 +351,6 @@ ...@@ -361,11 +351,6 @@
'base/encoder_vp8.h', 'base/encoder_vp8.h',
], ],
}], }],
['OS=="win"', {
'include_dirs': [
'../third_party/skia/include/config',
],
}],
], ],
}, # end of target 'remoting_base' }, # end of target 'remoting_base'
...@@ -379,9 +364,6 @@ ...@@ -379,9 +364,6 @@
'differ_block', 'differ_block',
'../crypto/crypto.gyp:crypto', '../crypto/crypto.gyp:crypto',
], ],
'include_dirs': [
'../skia/config',
],
'sources': [ 'sources': [
'host/access_verifier.h', 'host/access_verifier.h',
'host/capturer.h', 'host/capturer.h',
...@@ -468,11 +450,6 @@ ...@@ -468,11 +450,6 @@
], ],
}, },
}], }],
['OS=="win"', {
'include_dirs': [
'../third_party/skia/include/config',
],
}],
['OS=="mac"', { ['OS=="mac"', {
'sources': [ 'sources': [
'../third_party/GTM/AppKit/GTMCarbonEvent.h', '../third_party/GTM/AppKit/GTMCarbonEvent.h',
...@@ -505,9 +482,6 @@ ...@@ -505,9 +482,6 @@
'remoting_jingle_glue', 'remoting_jingle_glue',
'remoting_protocol', 'remoting_protocol',
], ],
'include_dirs': [
'../skia/config',
],
'sources': [ 'sources': [
'client/chromoting_client.cc', 'client/chromoting_client.cc',
'client/chromoting_client.h', 'client/chromoting_client.h',
...@@ -527,13 +501,6 @@ ...@@ -527,13 +501,6 @@
'client/rectangle_update_decoder.cc', 'client/rectangle_update_decoder.cc',
'client/rectangle_update_decoder.h', 'client/rectangle_update_decoder.h',
], ],
'conditions': [
['OS=="win"', {
'include_dirs': [
'../third_party/skia/include/config',
],
}],
],
}, # end of target 'remoting_client' }, # end of target 'remoting_client'
{ {
...@@ -547,9 +514,6 @@ ...@@ -547,9 +514,6 @@
'../base/base.gyp:base_i18n', '../base/base.gyp:base_i18n',
'../media/media.gyp:media', '../media/media.gyp:media',
], ],
'include_dirs': [
'../skia/config',
],
'sources': [ 'sources': [
'host/capturer_fake_ascii.cc', 'host/capturer_fake_ascii.cc',
'host/capturer_fake_ascii.h', 'host/capturer_fake_ascii.h',
...@@ -566,13 +530,6 @@ ...@@ -566,13 +530,6 @@
'../base/test/mock_chrome_application_mac.mm', '../base/test/mock_chrome_application_mac.mm',
'../base/test/mock_chrome_application_mac.h', '../base/test/mock_chrome_application_mac.h',
], ],
'conditions': [
['OS=="win"', {
'include_dirs': [
'../third_party/skia/include/config',
],
}],
],
}, # end of target 'remoting_simple_host' }, # end of target 'remoting_simple_host'
{ {
...@@ -726,6 +683,9 @@ ...@@ -726,6 +683,9 @@
{ {
'target_name': 'differ_block', 'target_name': 'differ_block',
'type': 'static_library', 'type': 'static_library',
'include_dirs': [
'..',
],
'dependencies': [ 'dependencies': [
'../media/media.gyp:cpu_features', '../media/media.gyp:cpu_features',
], ],
...@@ -745,6 +705,9 @@ ...@@ -745,6 +705,9 @@
{ {
'target_name': 'differ_block_sse2', 'target_name': 'differ_block_sse2',
'type': 'static_library', 'type': 'static_library',
'include_dirs': [
'..',
],
'conditions': [ 'conditions': [
[ 'os_posix == 1 and OS != "mac"', { [ 'os_posix == 1 and OS != "mac"', {
'cflags': [ 'cflags': [
...@@ -791,7 +754,6 @@ ...@@ -791,7 +754,6 @@
], ],
'include_dirs': [ 'include_dirs': [
'../testing/gmock/include', '../testing/gmock/include',
'../skia/config',
], ],
'sources': [ 'sources': [
'base/auth_token_util_unittest.cc', 'base/auth_token_util_unittest.cc',
...@@ -868,11 +830,6 @@ ...@@ -868,11 +830,6 @@
'base/encoder_vp8_unittest.cc', 'base/encoder_vp8_unittest.cc',
], ],
}], }],
['OS=="win"', {
'include_dirs': [
'../third_party/skia/include/config',
],
}],
], # end of 'conditions' ], # end of 'conditions'
}, # end of target 'remoting_unittests' }, # end of target 'remoting_unittests'
], # end of targets ], # end of targets
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define SKIA_EXT_SKIA_UTILS_MAC_H_ #define SKIA_EXT_SKIA_UTILS_MAC_H_
#pragma once #pragma once
#include <ApplicationServices/ApplicationServices.h> #include <CoreGraphics/CGColor.h>
#include <vector> #include <vector>
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment