diff options
32 files changed, 452 insertions, 498 deletions
diff --git a/remoting/DEPS b/remoting/DEPS index 89f92b7..324f7a5 100644 --- a/remoting/DEPS +++ b/remoting/DEPS @@ -5,9 +5,6 @@ include_rules = [ "-remoting", "+remoting/base", "+remoting/proto", - "+skia/config", - "+skia/ext", "+third_party/GTM", "+third_party/GTM/AppKit", - "+third_party/skia/include/core", ] diff --git a/remoting/base/capture_data.cc b/remoting/base/capture_data.cc index b66b239..1740447 100644 --- a/remoting/base/capture_data.cc +++ b/remoting/base/capture_data.cc @@ -1,4 +1,4 @@ -// 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 // found in the LICENSE file. @@ -17,6 +17,7 @@ CaptureData::CaptureData(const DataPlanes &data_planes, const gfx::Size& size, media::VideoFrame::Format format) : data_planes_(data_planes), + dirty_rects_(), size_(size), pixel_format_(format), capture_time_ms_(0), diff --git a/remoting/base/capture_data.h b/remoting/base/capture_data.h index ae5b89e..b8592fa 100644 --- a/remoting/base/capture_data.h +++ b/remoting/base/capture_data.h @@ -10,8 +10,7 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "media/base/video_frame.h" -#include "third_party/skia/include/core/SkRegion.h" -#include "ui/gfx/size.h" +#include "remoting/base/types.h" namespace remoting { @@ -31,11 +30,12 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> { const gfx::Size& size, 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_; } - // Get the dirty region from the previous capture. - const SkRegion& dirty_region() const { return dirty_region_; } + // Get the list of updated rectangles in the last capture. The result is + // written into |rects|. + const InvalidRects& dirty_rects() const { return dirty_rects_; } // Return the size of the image captured. gfx::Size size() const { return size_; } @@ -44,7 +44,7 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> { media::VideoFrame::Format pixel_format() const { return pixel_format_; } // Mutating methods. - SkRegion& mutable_dirty_region() { return dirty_region_; } + InvalidRects& mutable_dirty_rects() { return dirty_rects_; } // Return the time spent on capturing. int capture_time_ms() const { return capture_time_ms_; } @@ -62,7 +62,7 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> { private: const DataPlanes data_planes_; - SkRegion dirty_region_; + InvalidRects dirty_rects_; gfx::Size size_; media::VideoFrame::Format pixel_format_; diff --git a/remoting/base/codec_test.cc b/remoting/base/codec_test.cc index 0b62a63..d1b4978 100644 --- a/remoting/base/codec_test.cc +++ b/remoting/base/codec_test.cc @@ -1,11 +1,10 @@ -// 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 // found in the LICENSE file. #include <deque> #include <stdlib.h> -#include "base/memory/scoped_ptr.h" #include "media/base/video_frame.h" #include "remoting/base/base_mock_objects.h" #include "remoting/base/codec_test.h" @@ -13,18 +12,19 @@ #include "remoting/base/encoder.h" #include "remoting/base/util.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/rect.h" static const int kWidth = 320; static const int kHeight = 240; static const int kBytesPerPixel = 4; // Some sample rects for testing. -static const SkIRect kTestRects[] = { - SkIRect::MakeXYWH(0, 0, kWidth, kHeight), - SkIRect::MakeXYWH(0, 0, kWidth / 2, kHeight / 2), - SkIRect::MakeXYWH(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), - SkIRect::MakeXYWH(16, 16, 16, 16), - SkIRect::MakeXYWH(128, 64, 32, 32), +static const gfx::Rect kTestRects[] = { + gfx::Rect(0, 0, kWidth, kHeight), + gfx::Rect(0, 0, kWidth / 2, kHeight / 2), + gfx::Rect(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), + gfx::Rect(16, 16, 16, 16), + gfx::Rect(128, 64, 32, 32), }; namespace remoting { @@ -58,10 +58,10 @@ class EncoderMessageTester { ++begin_rect_; if (strict_) { - SkIRect rect = rects_.front(); + gfx::Rect rect = rects_.front(); rects_.pop_front(); - EXPECT_EQ(rect.fLeft, packet->format().x()); - EXPECT_EQ(rect.fTop, packet->format().y()); + EXPECT_EQ(rect.x(), packet->format().x()); + EXPECT_EQ(rect.y(), packet->format().y()); EXPECT_EQ(rect.width(), packet->format().width()); EXPECT_EQ(rect.height(), packet->format().height()); } @@ -93,7 +93,7 @@ class EncoderMessageTester { 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); added_rects_ += count; } @@ -111,7 +111,7 @@ class EncoderMessageTester { State state_; bool strict_; - std::deque<SkIRect> rects_; + std::deque<gfx::Rect> rects_; DISALLOW_COPY_AND_ASSIGN(EncoderMessageTester); }; @@ -152,7 +152,7 @@ class DecoderTester { 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); } @@ -165,8 +165,7 @@ class DecoderTester { // Test the content of the update rect. ASSERT_EQ(rects_.size(), update_rects_.size()); for (size_t i = 0; i < update_rects_.size(); ++i) { - SkIRect &r = rects_[i]; - gfx::Rect rect(r.fLeft, r.fTop, r.width(), r.height()); + gfx::Rect rect = rects_[i]; EXPECT_EQ(rect, update_rects_[i]); EXPECT_EQ(frame_->stride(0), capture_data_->data_planes().strides[0]); @@ -187,7 +186,7 @@ class DecoderTester { private: bool strict_; - std::deque<SkIRect> rects_; + std::deque<gfx::Rect> rects_; UpdatedRects update_rects_; Decoder* decoder_; scoped_refptr<media::VideoFrame> frame_; @@ -222,7 +221,7 @@ class EncoderTester { delete packet; } - void AddRects(const SkIRect* rects, int count) { + void AddRects(const gfx::Rect* rects, int count) { message_tester_->AddRects(rects, count); } @@ -264,10 +263,10 @@ scoped_refptr<CaptureData> PrepareEncodeData(media::VideoFrame::Format format, static void TestEncodingRects(Encoder* encoder, EncoderTester* tester, scoped_refptr<CaptureData> data, - const SkIRect* rects, int count) { - data->mutable_dirty_region().setEmpty(); + const gfx::Rect* rects, int count) { + data->mutable_dirty_rects().clear(); 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); @@ -284,22 +283,22 @@ void TestEncoder(Encoder* encoder, bool strict) { uint8* memory; scoped_refptr<CaptureData> data = PrepareEncodeData(media::VideoFrame::RGB32, &memory); - scoped_array<uint8> memory_wrapper(memory); TestEncodingRects(encoder, &tester, data, kTestRects, 1); TestEncodingRects(encoder, &tester, data, kTestRects + 1, 1); TestEncodingRects(encoder, &tester, data, kTestRects + 2, 1); TestEncodingRects(encoder, &tester, data, kTestRects + 3, 2); + delete [] memory; } static void TestEncodingRects(Encoder* encoder, EncoderTester* encoder_tester, DecoderTester* decoder_tester, scoped_refptr<CaptureData> data, - const SkIRect* rects, int count) { - data->mutable_dirty_region().setEmpty(); + const gfx::Rect* rects, int count) { + data->mutable_dirty_rects().clear(); 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); decoder_tester->AddRects(rects, count); @@ -307,12 +306,12 @@ static void TestEncodingRects(Encoder* encoder, // Generate random data for the updated rects. srand(0); 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 row_size = bytes_per_pixel * rect.width(); uint8* memory = data->data_planes().data[0] + - data->data_planes().strides[0] * rect.fTop + - bytes_per_pixel * rect.fLeft; + data->data_planes().strides[0] * rect.y() + + bytes_per_pixel * rect.x(); for (int y = 0; y < rect.height(); ++y) { for (int x = 0; x < row_size; ++x) memory[x] = rand() % 256; @@ -335,8 +334,6 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) { uint8* memory; scoped_refptr<CaptureData> data = PrepareEncodeData(media::VideoFrame::RGB32, &memory); - scoped_array<uint8> memory_wrapper(memory); - DecoderTester decoder_tester(decoder); decoder_tester.set_strict(strict); decoder_tester.set_capture_data(data); @@ -350,6 +347,7 @@ void TestEncoderDecoder(Encoder* encoder, Decoder* decoder, bool strict) { kTestRects + 2, 1); TestEncodingRects(encoder, &encoder_tester, &decoder_tester, data, kTestRects + 3, 2); + delete [] memory; } } // namespace remoting diff --git a/remoting/base/decoder.h b/remoting/base/decoder.h index b13483f..a0a9244 100644 --- a/remoting/base/decoder.h +++ b/remoting/base/decoder.h @@ -46,8 +46,6 @@ class Decoder { // Returns rects that were updated in the last frame. Can be called only // after DecodePacket returned DECODE_DONE. Caller keeps ownership of // |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; // Reset the decoder to an uninitialized state. Release all references to diff --git a/remoting/base/encoder_row_based.cc b/remoting/base/encoder_row_based.cc index 75af34a..8039869 100644 --- a/remoting/base/encoder_row_based.cc +++ b/remoting/base/encoder_row_based.cc @@ -1,4 +1,4 @@ -// 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 // found in the LICENSE file. @@ -66,19 +66,16 @@ void EncoderRowBased::Encode(scoped_refptr<CaptureData> capture_data, capture_data_ = capture_data; callback_.reset(data_available_callback); - const SkRegion& region = capture_data->dirty_region(); - SkRegion::Iterator iter(region); - while (!iter.done()) { - SkIRect rect = iter.rect(); - iter.next(); - EncodeRect(rect, iter.done()); + const InvalidRects& rects = capture_data->dirty_rects(); + for (InvalidRects::const_iterator r = rects.begin(); r != rects.end(); ++r) { + EncodeRect(*r, r == --rects.end()); } capture_data_ = NULL; 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]); const int strides = capture_data_->data_planes().strides[0]; const int bytes_per_pixel = GetBytesPerPixel(capture_data_->pixel_format()); @@ -89,7 +86,7 @@ void EncoderRowBased::EncodeRect(const SkIRect& rect, bool last) { VideoPacket* packet = new VideoPacket(); PrepareUpdateStart(rect, packet); 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. uint8* out = GetOutputBuffer(packet, packet_size_); int filled = 0; @@ -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) { packet->set_flags(packet->flags() | VideoPacket::FIRST_PACKET); VideoPacketFormat* format = packet->mutable_format(); - format->set_x(rect.fLeft); - format->set_y(rect.fTop); + format->set_x(rect.x()); + format->set_y(rect.y()); format->set_width(rect.width()); format->set_height(rect.height()); format->set_encoding(encoding_); diff --git a/remoting/base/encoder_row_based.h b/remoting/base/encoder_row_based.h index 6da2cd5..d453ffb 100644 --- a/remoting/base/encoder_row_based.h +++ b/remoting/base/encoder_row_based.h @@ -1,4 +1,4 @@ -// 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 // found in the LICENSE file. @@ -7,8 +7,8 @@ #include "remoting/base/encoder.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 { @@ -41,10 +41,10 @@ class EncoderRowBased : public Encoder { int packet_size); // 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. - 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 // encoded rectangle data. Will resize the buffer to |size|. diff --git a/remoting/base/encoder_vp8.cc b/remoting/base/encoder_vp8.cc index 5616bba..447e5d5 100644 --- a/remoting/base/encoder_vp8.cc +++ b/remoting/base/encoder_vp8.cc @@ -10,7 +10,6 @@ #include "remoting/base/capture_data.h" #include "remoting/base/util.h" #include "remoting/proto/video.pb.h" -#include "third_party/skia/include/core/SkRegion.h" extern "C" { #define VPX_CODEC_DISABLE_COMPAT 1 @@ -149,7 +148,7 @@ bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data, 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 int in_stride = capture_data->data_planes().strides[0]; const int plane_size = @@ -161,11 +160,9 @@ bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data, const int uv_stride = image_->stride[1]; 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. - SkIRect skRect = r.rect(); - gfx::Rect rect(skRect.fLeft, skRect.fTop, skRect.width(), skRect.height()); - rect = AlignAndClipRect(rect, image_->w, image_->h); + gfx::Rect rect = AlignAndClipRect(*r, image_->w, image_->h); if (!rect.IsEmpty()) updated_rects->push_back(rect); diff --git a/remoting/base/types.h b/remoting/base/types.h new file mode 100644 index 0000000..1c93f6f --- /dev/null +++ b/remoting/base/types.h @@ -0,0 +1,21 @@ +// 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_ diff --git a/remoting/base/util.cc b/remoting/base/util.cc index 483d97f..8671eeb 100644 --- a/remoting/base/util.cc +++ b/remoting/base/util.cc @@ -161,11 +161,11 @@ void CopyRect(const uint8* src_plane, uint8* dest_plane, int dest_plane_stride, int bytes_per_pixel, - const SkIRect& rect) { + const gfx::Rect& rect) { // Get the address of the starting point. - const int src_y_offset = src_plane_stride * rect.fTop; - const int dest_y_offset = dest_plane_stride * rect.fTop; - const int x_offset = bytes_per_pixel * rect.fLeft; + const int src_y_offset = src_plane_stride * rect.y(); + const int dest_y_offset = dest_plane_stride * rect.y(); + const int x_offset = bytes_per_pixel * rect.x(); src_plane += src_y_offset + x_offset; dest_plane += dest_y_offset + x_offset; diff --git a/remoting/base/util.h b/remoting/base/util.h index 262b551..d0e0b0d 100644 --- a/remoting/base/util.h +++ b/remoting/base/util.h @@ -6,7 +6,6 @@ #define REMOTING_BASE_UTIL_H_ #include "media/base/video_frame.h" -#include "third_party/skia/include/core/SkRect.h" #include "ui/gfx/rect.h" namespace remoting { @@ -65,7 +64,7 @@ void CopyRect(const uint8* src_plane, uint8* dest_plane, int dest_plane_stride, int bytes_per_pixel, - const SkIRect& rect); + const gfx::Rect& rect); } // namespace remoting diff --git a/remoting/host/capturer.h b/remoting/host/capturer.h index 7d74c17..5b95294 100644 --- a/remoting/host/capturer.h +++ b/remoting/host/capturer.h @@ -8,7 +8,7 @@ #include "base/basictypes.h" #include "base/callback_old.h" #include "remoting/base/capture_data.h" -#include "third_party/skia/include/core/SkRegion.h" +#include "remoting/base/types.h" namespace remoting { @@ -51,11 +51,11 @@ class Capturer { // Return the pixel format of the screen. virtual media::VideoFrame::Format pixel_format() const = 0; - // Clear out the invalid region. - virtual void ClearInvalidRegion() = 0; + // Clear out the list of invalid rects. + virtual void ClearInvalidRects() = 0; - // Invalidate the specified region. - virtual void InvalidateRegion(const SkRegion& invalid_region) = 0; + // Invalidate the specified screen rects. + virtual void InvalidateRects(const InvalidRects& inval_rects) = 0; // Invalidate the entire screen, of a given size. virtual void InvalidateScreen(const gfx::Size& size) = 0; @@ -65,15 +65,19 @@ class Capturer { virtual void InvalidateFullScreen() = 0; // Capture the screen data associated with each of the accumulated - // dirty region. - // When the capture is complete, |callback| is called even if the dirty region - // is empty. + // rects in |inval_rects|. + // This routine will first call CalculateInvalidRects to update the + // 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 - // data of the previous capture. + // data of the last capture. // There can be at most one concurrent read going on when this // method is called. - virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) = 0; + virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) = 0; // Get the size of the most recently captured screen. virtual const gfx::Size& size_most_recent() const = 0; diff --git a/remoting/host/capturer_fake.cc b/remoting/host/capturer_fake.cc index 717e0ad..8f81b5b 100644 --- a/remoting/host/capturer_fake.cc +++ b/remoting/host/capturer_fake.cc @@ -54,12 +54,12 @@ media::VideoFrame::Format CapturerFake::pixel_format() const { return pixel_format_; } -void CapturerFake::ClearInvalidRegion() { - helper.ClearInvalidRegion(); +void CapturerFake::ClearInvalidRects() { + helper.ClearInvalidRects(); } -void CapturerFake::InvalidateRegion(const SkRegion& invalid_region) { - helper.InvalidateRegion(invalid_region); +void CapturerFake::InvalidateRects(const InvalidRects& inval_rects) { + helper.InvalidateRects(inval_rects); } void CapturerFake::InvalidateScreen(const gfx::Size& size) { @@ -70,14 +70,14 @@ void CapturerFake::InvalidateFullScreen() { helper.InvalidateFullScreen(); } -void CapturerFake::CaptureInvalidRegion(CaptureCompletedCallback* callback) { +void CapturerFake::CaptureInvalidRects(CaptureCompletedCallback* callback) { scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); GenerateImage(); InvalidateScreen(size_); - SkRegion invalid_region; - helper.SwapInvalidRegion(&invalid_region); + InvalidRects inval_rects; + helper.SwapInvalidRects(inval_rects); DataPlanes planes; planes.data[0] = buffers_[current_buffer_].get(); @@ -87,7 +87,7 @@ void CapturerFake::CaptureInvalidRegion(CaptureCompletedCallback* callback) { scoped_refptr<CaptureData> capture_data(new CaptureData(planes, size_, pixel_format_)); - capture_data->mutable_dirty_region() = invalid_region; + capture_data->mutable_dirty_rects() = inval_rects; helper.set_size_most_recent(capture_data->size()); diff --git a/remoting/host/capturer_fake.h b/remoting/host/capturer_fake.h index 61f41283..879ee03 100644 --- a/remoting/host/capturer_fake.h +++ b/remoting/host/capturer_fake.h @@ -21,15 +21,14 @@ class CapturerFake : public Capturer { virtual ~CapturerFake(); // Capturer interface. - virtual void ScreenConfigurationChanged() OVERRIDE; - virtual media::VideoFrame::Format pixel_format() const OVERRIDE; - virtual void ClearInvalidRegion() OVERRIDE; - virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; - virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; - virtual void InvalidateFullScreen() OVERRIDE; - virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) - OVERRIDE; - virtual const gfx::Size& size_most_recent() const OVERRIDE; + virtual void ScreenConfigurationChanged(); + virtual media::VideoFrame::Format pixel_format() const; + virtual void ClearInvalidRects(); + virtual void InvalidateRects(const InvalidRects& inval_rects); + virtual void InvalidateScreen(const gfx::Size& size); + virtual void InvalidateFullScreen(); + virtual void CaptureInvalidRects(CaptureCompletedCallback* callback); + virtual const gfx::Size& size_most_recent() const; private: // Generates an image in the front buffer. diff --git a/remoting/host/capturer_fake_ascii.cc b/remoting/host/capturer_fake_ascii.cc index e24bebd..40f4509 100644 --- a/remoting/host/capturer_fake_ascii.cc +++ b/remoting/host/capturer_fake_ascii.cc @@ -37,23 +37,23 @@ media::VideoFrame::Format CapturerFakeAscii::pixel_format() const { return pixel_format_; } -void CapturerFakeAscii::ClearInvalidRegion() { - helper_.ClearInvalidRegion(); +void CapturerFakeAscii::ClearInvalidRects() { + helper.ClearInvalidRects(); } -void CapturerFakeAscii::InvalidateRegion(const SkRegion& invalid_region) { - helper_.InvalidateRegion(invalid_region); +void CapturerFakeAscii::InvalidateRects(const InvalidRects& inval_rects) { + helper.InvalidateRects(inval_rects); } void CapturerFakeAscii::InvalidateScreen(const gfx::Size& size) { - helper_.InvalidateScreen(size); + helper.InvalidateScreen(size); } void CapturerFakeAscii::InvalidateFullScreen() { - helper_.InvalidateFullScreen(); + helper.InvalidateFullScreen(); } -void CapturerFakeAscii::CaptureInvalidRegion( +void CapturerFakeAscii::CaptureInvalidRects( CaptureCompletedCallback* callback) { scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); @@ -65,13 +65,13 @@ void CapturerFakeAscii::CaptureInvalidRegion( scoped_refptr<CaptureData> capture_data(new CaptureData( 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); } const gfx::Size& CapturerFakeAscii::size_most_recent() const { - return helper_.size_most_recent(); + return helper.size_most_recent(); } void CapturerFakeAscii::GenerateImage() { diff --git a/remoting/host/capturer_fake_ascii.h b/remoting/host/capturer_fake_ascii.h index a7c0d3c..2f348ad 100644 --- a/remoting/host/capturer_fake_ascii.h +++ b/remoting/host/capturer_fake_ascii.h @@ -22,14 +22,13 @@ class CapturerFakeAscii : public Capturer { virtual ~CapturerFakeAscii(); // Capturer interface. - virtual void ScreenConfigurationChanged() OVERRIDE; - virtual media::VideoFrame::Format pixel_format() const OVERRIDE; - virtual void ClearInvalidRegion() OVERRIDE; - virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; - virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; - virtual void InvalidateFullScreen() OVERRIDE; - virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) - OVERRIDE; + virtual void ScreenConfigurationChanged(); + virtual media::VideoFrame::Format pixel_format() const; + virtual void ClearInvalidRects(); + virtual void InvalidateRects(const InvalidRects& inval_rects); + virtual void InvalidateScreen(const gfx::Size& size); + virtual void InvalidateFullScreen(); + virtual void CaptureInvalidRects(CaptureCompletedCallback* callback); virtual const gfx::Size& size_most_recent() const; private: @@ -41,7 +40,7 @@ class CapturerFakeAscii : public Capturer { int height_; int bytes_per_row_; - CapturerHelper helper_; + CapturerHelper helper; // We have two buffers for the screen images as required by Capturer. static const int kNumBuffers = 2; diff --git a/remoting/host/capturer_helper.cc b/remoting/host/capturer_helper.cc index 8cb0295..eba7c12 100644 --- a/remoting/host/capturer_helper.cc +++ b/remoting/host/capturer_helper.cc @@ -4,6 +4,9 @@ #include "remoting/host/capturer_helper.h" +#include <algorithm> +#include <iterator> + namespace remoting { CapturerHelper::CapturerHelper() : size_most_recent_(0, 0) { @@ -12,20 +15,24 @@ CapturerHelper::CapturerHelper() : size_most_recent_(0, 0) { CapturerHelper::~CapturerHelper() { } -void CapturerHelper::ClearInvalidRegion() { - base::AutoLock auto_invalid_region_lock(invalid_region_lock_); - invalid_region_.setEmpty(); +void CapturerHelper::ClearInvalidRects() { + base::AutoLock auto_inval_rects_lock(inval_rects_lock_); + inval_rects_.clear(); } -void CapturerHelper::InvalidateRegion(const SkRegion& invalid_region) { - base::AutoLock auto_invalid_region_lock(invalid_region_lock_); - invalid_region_.op(invalid_region, SkRegion::kUnion_Op); +void CapturerHelper::InvalidateRects(const InvalidRects& inval_rects) { + base::AutoLock auto_inval_rects_lock(inval_rects_lock_); + 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) { - base::AutoLock auto_invalid_region_lock(invalid_region_lock_); - invalid_region_.op(SkIRect::MakeWH(size.width(), size.height()), - SkRegion::kUnion_Op); + base::AutoLock auto_inval_rects_lock(inval_rects_lock_); + inval_rects_.clear(); + inval_rects_.insert(gfx::Rect(0, 0, size.width(), size.height())); } void CapturerHelper::InvalidateFullScreen() { @@ -33,17 +40,17 @@ void CapturerHelper::InvalidateFullScreen() { InvalidateScreen(size_most_recent_); } -// TODO: Is this actually required? -// http://crbug.com/92346 bool CapturerHelper::IsCaptureFullScreen(const gfx::Size& size) { - base::AutoLock auto_invalid_region_lock(invalid_region_lock_); - SkRegion fullScreenRegion(SkIRect::MakeWH(size.width(), size.height())); - return fullScreenRegion == invalid_region_; + base::AutoLock auto_inval_rects_lock(inval_rects_lock_); + return inval_rects_.size() == 1u && + 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) { - base::AutoLock auto_invalid_region_lock(invalid_region_lock_); - invalid_region->swap(invalid_region_); +void CapturerHelper::SwapInvalidRects(InvalidRects& inval_rects) { + base::AutoLock auto_inval_rects_lock(inval_rects_lock_); + inval_rects.swap(inval_rects_); } const gfx::Size& CapturerHelper::size_most_recent() const { diff --git a/remoting/host/capturer_helper.h b/remoting/host/capturer_helper.h index 36968a1..b7650c0 100644 --- a/remoting/host/capturer_helper.h +++ b/remoting/host/capturer_helper.h @@ -6,24 +6,24 @@ #define REMOTING_HOST_CAPTURER_HELPER_H_ #include "base/synchronization/lock.h" -#include "third_party/skia/include/core/SkRegion.h" -#include "ui/gfx/size.h" +#include "remoting/base/types.h" namespace remoting { // 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 -// most recently captured screen, on behalf of the Capturer that owns it. +// interface. It maintains a thread-safe list of invalid rectangles, and the +// size of the most recently captured screen, on behalf of the Capturer that +// owns it. class CapturerHelper { public: CapturerHelper(); ~CapturerHelper(); - // Clear out the invalid region. - void ClearInvalidRegion(); + // Clear out the list of invalid rects. + void ClearInvalidRects(); - // Invalidate the specified region. - void InvalidateRegion(const SkRegion& invalid_region); + // Invalidate the specified screen rects. + void InvalidateRects(const InvalidRects& inval_rects); // Invalidate the entire screen, of a given size. void InvalidateScreen(const gfx::Size& size); @@ -35,21 +35,29 @@ class CapturerHelper { // Whether the invalid region is a full screen of a given size. bool IsCaptureFullScreen(const gfx::Size& size); - // Swap the given region with the stored invalid region. - void SwapInvalidRegion(SkRegion* invalid_region); + // Swap the given set of rects with the stored invalid rects. + // 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. const gfx::Size& size_most_recent() const; void set_size_most_recent(const gfx::Size& size); private: - // A region that has been manually invalidated (through InvalidateRegion). - // These will be returned as dirty_region in the capture data during the next + // Rects that have been manually invalidated (through InvalidateRect). + // These will be returned as dirty_rects in the capture data during the next // capture. - SkRegion invalid_region_; + InvalidRects inval_rects_; - // A lock protecting |invalid_region_| across threads. - base::Lock invalid_region_lock_; + // A lock protecting |inval_rects_| across threads. + base::Lock inval_rects_lock_; // The size of the most recently captured screen. gfx::Size size_most_recent_; diff --git a/remoting/host/capturer_linux.cc b/remoting/host/capturer_linux.cc index dc68cf6..0c79715 100644 --- a/remoting/host/capturer_linux.cc +++ b/remoting/host/capturer_linux.cc @@ -13,6 +13,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "remoting/base/types.h" #include "remoting/host/capturer_helper.h" #include "remoting/host/differ.h" #include "remoting/host/x_server_pixel_buffer.h" @@ -74,12 +75,11 @@ class CapturerLinux : public Capturer { // Capturer interface. virtual void ScreenConfigurationChanged() OVERRIDE; virtual media::VideoFrame::Format pixel_format() const OVERRIDE; - virtual void ClearInvalidRegion() OVERRIDE; - virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; + virtual void ClearInvalidRects() OVERRIDE; + virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE; virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; virtual void InvalidateFullScreen() OVERRIDE; - virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) - OVERRIDE; + virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE; virtual const gfx::Size& size_most_recent() const OVERRIDE; private: @@ -114,12 +114,12 @@ class CapturerLinux : public Capturer { // Capture a rectangle from |x_server_pixel_buffer_|, and copy the data into // |capture_data|. - void CaptureRect(const SkIRect& rect, CaptureData* capture_data); + void CaptureRect(const gfx::Rect& rect, CaptureData* capture_data); // We expose two forms of blitting to handle variations in the pixel format. // In FastBlit, the operation is effectively a memcpy. - void FastBlit(uint8* image, const SkIRect& rect, CaptureData* capture_data); - void SlowBlit(uint8* image, const SkIRect& rect, CaptureData* capture_data); + void FastBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data); + void SlowBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data); // X11 graphics context. Display* display_; @@ -147,9 +147,9 @@ class CapturerLinux : public Capturer { // Format of pixels returned in buffer. media::VideoFrame::Format pixel_format_; - // Invalid region from the previous capture. This is used to synchronize the - // current with the last buffer used. - SkRegion last_invalid_region_; + // Invalid rects in the last capture. This is used to synchronize current with + // the previous buffer used. + InvalidRects last_invalid_rects_; // Last capture buffer used. uint8* last_buffer_; @@ -240,7 +240,8 @@ void CapturerLinux::ScreenConfigurationChanged() { for (int i = 0; i < kNumBuffers; ++i) { buffers_[i].set_needs_update(); } - helper_.ClearInvalidRegion(); + InvalidRects rects; + helper_.SwapInvalidRects(rects); x_server_pixel_buffer_.Init(display_); } @@ -248,12 +249,12 @@ media::VideoFrame::Format CapturerLinux::pixel_format() const { return pixel_format_; } -void CapturerLinux::ClearInvalidRegion() { - helper_.ClearInvalidRegion(); +void CapturerLinux::ClearInvalidRects() { + helper_.ClearInvalidRects(); } -void CapturerLinux::InvalidateRegion(const SkRegion& invalid_region) { - helper_.InvalidateRegion(invalid_region); +void CapturerLinux::InvalidateRects(const InvalidRects& inval_rects) { + helper_.InvalidateRects(inval_rects); } void CapturerLinux::InvalidateScreen(const gfx::Size& size) { @@ -265,7 +266,7 @@ void CapturerLinux::InvalidateFullScreen() { last_buffer_ = NULL; } -void CapturerLinux::CaptureInvalidRegion( +void CapturerLinux::CaptureInvalidRects( CaptureCompletedCallback* callback) { scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); @@ -296,7 +297,7 @@ void CapturerLinux::ProcessPendingXEvents() { // on XPending because we want to guarantee this terminates. int events_to_process = XPending(display_); XEvent e; - SkRegion invalid_region; + InvalidRects invalid_rects; for (int i = 0; i < events_to_process; i++) { XNextEvent(display_, &e); @@ -307,23 +308,21 @@ void CapturerLinux::ProcessPendingXEvents() { if (event->area.width <= 0 || event->area.height <= 0) continue; - SkIRect damage_rect = SkIRect::MakeXYWH(event->area.x, - event->area.y, - event->area.width, - event->area.height); - invalid_region.op(damage_rect, SkRegion::kUnion_Op); - DVLOG(3) << "Damage received for rect at (" - << damage_rect.fLeft << "," << damage_rect.fTop << ") size (" - << damage_rect.width() << "," << damage_rect.height() << ")"; + gfx::Rect damage_rect(event->area.x, event->area.y, event->area.width, + event->area.height); + invalid_rects.insert(damage_rect); + VLOG(3) << "Damage received for rect at (" + << damage_rect.x() << "," << damage_rect.y() << ") size (" + << damage_rect.width() << "," << damage_rect.height() << ")"; } else if (e.type == ConfigureNotify) { ScreenConfigurationChanged(); - invalid_region.setEmpty(); + invalid_rects.clear(); } else { LOG(WARNING) << "Got unknown event type: " << e.type; } } - helper_.InvalidateRegion(invalid_region); + helper_.InvalidateRects(invalid_rects); } CaptureData* CapturerLinux::CaptureFrame() { @@ -342,60 +341,60 @@ CaptureData* CapturerLinux::CaptureFrame() { if (use_damage_ && last_buffer_) SynchronizeFrame(); - SkRegion invalid_region; + InvalidRects invalid_rects; x_server_pixel_buffer_.Synchronize(); if (use_damage_ && last_buffer_) { - helper_.SwapInvalidRegion(&invalid_region); - for (SkRegion::Iterator it(invalid_region); !it.done(); it.next()) { - CaptureRect(it.rect(), capture_data); + helper_.SwapInvalidRects(invalid_rects); + for (InvalidRects::const_iterator it = invalid_rects.begin(); + it != invalid_rects.end(); + ++it) { + CaptureRect(*it, capture_data); } // TODO(ajwong): We should only repair the rects that were copied! XDamageSubtract(display_, damage_handle_, None, None); } else { // Doing full-screen polling, or this is the first capture after a // screen-resolution change. In either case, need a full-screen capture. - SkIRect screen_rect = SkIRect::MakeWH(buffer.size().width(), - buffer.size().height()); + gfx::Rect screen_rect(buffer.size()); CaptureRect(screen_rect, capture_data); if (last_buffer_) { // Full-screen polling, so calculate the invalid rects here, based on the // changed pixels between current and previous buffers. DCHECK(differ_ != NULL); - differ_->CalcDirtyRegion(last_buffer_, buffer.ptr(), &invalid_region); + differ_->CalcDirtyRects(last_buffer_, buffer.ptr(), &invalid_rects); } else { // No previous buffer, so always invalidate the whole screen, whether // or not DAMAGE is being used. DAMAGE doesn't necessarily send a // full-screen notification after a screen-resolution change, so // this is done here. - invalid_region.op(screen_rect, SkRegion::kUnion_Op); + invalid_rects.insert(screen_rect); } } - capture_data->mutable_dirty_region() = invalid_region; - last_invalid_region_ = invalid_region; + capture_data->mutable_dirty_rects() = invalid_rects; + last_invalid_rects_ = invalid_rects; last_buffer_ = buffer.ptr(); return capture_data; } void CapturerLinux::SynchronizeFrame() { - // Synchronize the current buffer with the previous one since we do not - // capture the entire desktop. Note that encoder may be reading from the - // previous buffer at this time so thread access complaints are false - // positives. + // Synchronize the current buffer with the last one since we do not capture + // the entire desktop. Note that encoder may be reading from the previous + // buffer at this time so thread access complaints are false positives. // TODO(hclam): We can reduce the amount of copying here by subtracting - // |capturer_helper_|s region from |last_invalid_region_|. - // http://crbug.com/92354 + // |rects| from |last_invalid_rects_|. DCHECK(last_buffer_); VideoFrameBuffer& buffer = buffers_[current_buffer_]; - for (SkRegion::Iterator it(last_invalid_region_); !it.done(); it.next()) { - const SkIRect& r = it.rect(); - int offset = r.fTop * buffer.bytes_per_row() + r.fLeft * kBytesPerPixel; - for (int i = 0; i < r.height(); ++i) { + for (InvalidRects::const_iterator it = last_invalid_rects_.begin(); + it != last_invalid_rects_.end(); + ++it) { + int offset = it->y() * buffer.bytes_per_row() + it->x() * kBytesPerPixel; + for (int i = 0; i < it->height(); ++i) { memcpy(buffer.ptr() + offset, last_buffer_ + offset, - r.width() * kBytesPerPixel); + it->width() * kBytesPerPixel); offset += buffer.size().width() * kBytesPerPixel; } } @@ -413,26 +412,26 @@ void CapturerLinux::DeinitXlib() { } } -void CapturerLinux::CaptureRect(const SkIRect& rect, +void CapturerLinux::CaptureRect(const gfx::Rect& rect, CaptureData* capture_data) { uint8* image = x_server_pixel_buffer_.CaptureRect(rect); int depth = x_server_pixel_buffer_.GetDepth(); int bpp = x_server_pixel_buffer_.GetBitsPerPixel(); bool is_rgb = x_server_pixel_buffer_.IsRgb(); if ((depth == 24 || depth == 32) && bpp == 32 && is_rgb) { - DVLOG(3) << "Fast blitting"; + VLOG(3) << "Fast blitting"; FastBlit(image, rect, capture_data); } else { - DVLOG(3) << "Slow blitting"; + VLOG(3) << "Slow blitting"; SlowBlit(image, rect, capture_data); } } -void CapturerLinux::FastBlit(uint8* image, const SkIRect& rect, +void CapturerLinux::FastBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data) { uint8* src_pos = image; int src_stride = x_server_pixel_buffer_.GetStride(); - int dst_x = rect.fLeft, dst_y = rect.fTop; + int dst_x = rect.x(), dst_y = rect.y(); DataPlanes planes = capture_data->data_planes(); uint8* dst_buffer = planes.data[0]; @@ -450,13 +449,13 @@ void CapturerLinux::FastBlit(uint8* image, const SkIRect& rect, } } -void CapturerLinux::SlowBlit(uint8* image, const SkIRect& rect, +void CapturerLinux::SlowBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data) { DataPlanes planes = capture_data->data_planes(); uint8* dst_buffer = planes.data[0]; const int dst_stride = planes.strides[0]; int src_stride = x_server_pixel_buffer_.GetStride(); - int dst_x = rect.fLeft, dst_y = rect.fTop; + int dst_x = rect.x(), dst_y = rect.y(); int width = rect.width(), height = rect.height(); unsigned int red_mask = x_server_pixel_buffer_.GetRedMask(); diff --git a/remoting/host/capturer_mac.cc b/remoting/host/capturer_mac.cc index 5bdd176..bb9f8591 100644 --- a/remoting/host/capturer_mac.cc +++ b/remoting/host/capturer_mac.cc @@ -15,7 +15,6 @@ #include "base/memory/scoped_ptr.h" #include "remoting/base/util.h" #include "remoting/host/capturer_helper.h" -#include "skia/ext/skia_utils_mac.h" namespace remoting { @@ -135,20 +134,19 @@ class CapturerMac : public Capturer { // Capturer interface. virtual void ScreenConfigurationChanged() OVERRIDE; virtual media::VideoFrame::Format pixel_format() const OVERRIDE; - virtual void ClearInvalidRegion() OVERRIDE; - virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; + virtual void ClearInvalidRects() OVERRIDE; + virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE; virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; virtual void InvalidateFullScreen() OVERRIDE; - virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) - OVERRIDE; + virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE; virtual const gfx::Size& size_most_recent() const OVERRIDE; private: - void GlBlitFast(const VideoFrameBuffer& buffer, const SkRegion& region); + void GlBlitFast(const VideoFrameBuffer& buffer, const InvalidRects& rects); void GlBlitSlow(const VideoFrameBuffer& buffer); - void CgBlit(const VideoFrameBuffer& buffer, const SkRegion& region); - void CaptureRegion(const SkRegion& region, - CaptureCompletedCallback* callback); + void CgBlit(const VideoFrameBuffer& buffer, const InvalidRects& rects); + void CaptureRects(const InvalidRects& rects, + CaptureCompletedCallback* callback); void ScreenRefresh(CGRectCount count, const CGRect *rect_array); void ScreenUpdateMove(CGScreenUpdateMoveDelta delta, @@ -178,12 +176,12 @@ class CapturerMac : public Capturer { // The current buffer with valid data for reading. int current_buffer_; - // The previous buffer into which we captured, or NULL for the first capture - // for a particular screen resolution. + // The last buffer into which we captured, or NULL for the first capture for + // a particular screen resolution. uint8* last_buffer_; - // Contains an invalid region from the previous capture. - SkRegion last_invalid_region_; + // Contains a list of invalid rectangles in the last capture. + InvalidRects last_invalid_rects_; // Format of pixels returned in buffer. media::VideoFrame::Format pixel_format_; @@ -242,7 +240,8 @@ void CapturerMac::ReleaseBuffers() { void CapturerMac::ScreenConfigurationChanged() { ReleaseBuffers(); - helper_.ClearInvalidRegion(); + InvalidRects rects; + helper_.SwapInvalidRects(rects); last_buffer_ = NULL; CGDirectDisplayID mainDevice = CGMainDisplayID(); @@ -281,12 +280,12 @@ media::VideoFrame::Format CapturerMac::pixel_format() const { return pixel_format_; } -void CapturerMac::ClearInvalidRegion() { - helper_.ClearInvalidRegion(); +void CapturerMac::ClearInvalidRects() { + helper_.ClearInvalidRects(); } -void CapturerMac::InvalidateRegion(const SkRegion& invalid_region) { - helper_.InvalidateRegion(invalid_region); +void CapturerMac::InvalidateRects(const InvalidRects& inval_rects) { + helper_.InvalidateRects(inval_rects); } void CapturerMac::InvalidateScreen(const gfx::Size& size) { @@ -297,25 +296,25 @@ void CapturerMac::InvalidateFullScreen() { helper_.InvalidateFullScreen(); } -void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) { +void CapturerMac::CaptureInvalidRects(CaptureCompletedCallback* callback) { scoped_refptr<CaptureData> data; if (capturing_) { - SkRegion region; - helper_.SwapInvalidRegion(®ion); + InvalidRects rects; + helper_.SwapInvalidRects(rects); VideoFrameBuffer& current_buffer = buffers_[current_buffer_]; current_buffer.Update(); bool flip = true; // GL capturers need flipping. if (cgl_context_) { if (pixel_buffer_object_.get() != 0) { - GlBlitFast(current_buffer, region); + GlBlitFast(current_buffer, rects); } else { // See comment in scoped_pixel_buffer_object::Init about why the slow // path is always used on 10.5. GlBlitSlow(current_buffer); } } else { - CgBlit(current_buffer, region); + CgBlit(current_buffer, rects); flip = false; } @@ -330,7 +329,7 @@ void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) { data = new CaptureData(planes, gfx::Size(current_buffer.size()), pixel_format()); - data->mutable_dirty_region() = region; + data->mutable_dirty_rects() = rects; current_buffer_ = (current_buffer_ + 1) % kNumBuffers; helper_.set_size_most_recent(data->size()); @@ -341,28 +340,31 @@ void CapturerMac::CaptureInvalidRegion(CaptureCompletedCallback* callback) { } void CapturerMac::GlBlitFast(const VideoFrameBuffer& buffer, - const SkRegion& region) { + const InvalidRects& rects) { if (last_buffer_) { // 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. - // TODO(hclam): We can reduce the amount of copying here by subtracting - // |capturer_helper_|s region from |last_invalid_region_|. - // http://crbug.com/92354 + // invalid rects in the last capture in the current buffer. + // TODO(hclam): |last_invalid_rects_| and |rects| can overlap and this + // causes extra copies on the overlapped region. Subtract |rects| from + // |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 // magic here to copy the correct rectangle. 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, -buffer.bytes_per_row(), buffer.ptr() + y_offset, -buffer.bytes_per_row(), 4, // Bytes for pixel for RGBA. - i.rect()); + *i); } } last_buffer_ = buffer.ptr(); - last_invalid_region_ = region; + last_invalid_rects_ = rects; CGLContextObj CGL_MACRO_CONTEXT = cgl_context_; glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_.get()); @@ -378,13 +380,13 @@ void CapturerMac::GlBlitFast(const VideoFrameBuffer& buffer, // 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. 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, -buffer.bytes_per_row(), buffer.ptr() + y_offset, -buffer.bytes_per_row(), 4, // Bytes for pixel for RGBA. - i.rect()); + *i); } } if (!glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB)) { @@ -413,7 +415,7 @@ void CapturerMac::GlBlitSlow(const VideoFrameBuffer& buffer) { } void CapturerMac::CgBlit(const VideoFrameBuffer& buffer, - const SkRegion& region) { + const InvalidRects& rects) { if (last_buffer_) memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer.size().height()); @@ -423,16 +425,13 @@ void CapturerMac::CgBlit(const VideoFrameBuffer& buffer, reinterpret_cast<uint8*>(CGDisplayBaseAddress(main_display)); int src_bytes_per_row = CGDisplayBytesPerRow(main_display); int src_bytes_per_pixel = CGDisplayBitsPerPixel(main_display) / 8; - // TODO(hclam): We can reduce the amount of copying here by subtracting - // |capturer_helper_|s region from |last_invalid_region_|. - // http://crbug.com/92354 - for(SkRegion::Iterator i(region); !i.done(); i.next()) { + for (InvalidRects::iterator i = rects.begin(); i != rects.end(); ++i) { CopyRect(display_base_address, src_bytes_per_row, buffer.ptr(), buffer.bytes_per_row(), src_bytes_per_pixel, - i.rect()); + *i); } } @@ -441,27 +440,24 @@ const gfx::Size& CapturerMac::size_most_recent() const { } void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) { - SkIRect skirect_array[count]; + InvalidRects rects; for (CGRectCount i = 0; i < count; ++i) { - skirect_array[i] = gfx::CGRectToSkIRect(rect_array[i]); + rects.insert(gfx::Rect(rect_array[i])); } - SkRegion region; - region.setRects(skirect_array, count); - InvalidateRegion(region); + InvalidateRects(rects); } void CapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta, size_t count, const CGRect *rect_array) { - SkIRect skirect_new_array[count]; + InvalidRects rects; for (CGRectCount i = 0; i < count; ++i) { CGRect rect = rect_array[i]; + rects.insert(gfx::Rect(rect)); rect = CGRectOffset(rect, delta.dX, delta.dY); - skirect_new_array[i] = gfx::CGRectToSkIRect(rect); + rects.insert(gfx::Rect(rect)); } - SkRegion region; - region.setRects(skirect_new_array, count); - InvalidateRegion(region); + InvalidateRects(rects); } void CapturerMac::ScreenRefreshCallback(CGRectCount count, diff --git a/remoting/host/capturer_mac_unittest.cc b/remoting/host/capturer_mac_unittest.cc index 681282b..e28b841 100644 --- a/remoting/host/capturer_mac_unittest.cc +++ b/remoting/host/capturer_mac_unittest.cc @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/memory/scoped_ptr.h" +#include "remoting/base/types.h" #include "testing/gtest/include/gtest/gtest.h" namespace remoting { @@ -21,12 +22,11 @@ class CapturerMacTest : public testing::Test { } void AddDirtyRect() { - SkIRect rect = SkIRect::MakeXYWH(0, 0, 10, 10); - region_.op(rect, SkRegion::kUnion_Op); + rects_.insert(gfx::Rect(0, 0, 10, 10)); } scoped_ptr<Capturer> capturer_; - SkRegion region_; + InvalidRects rects_; }; // CapturerCallback1 verifies that the whole screen is initially dirty. @@ -44,20 +44,21 @@ void CapturerCallback1::CaptureDoneCallback( CGDirectDisplayID mainDevice = CGMainDisplayID(); int width = CGDisplayPixelsWide(mainDevice); int height = CGDisplayPixelsHigh(mainDevice); - SkRegion initial_region(SkIRect::MakeXYWH(0, 0, width, height)); - EXPECT_EQ(initial_region, capture_data->dirty_region()); + InvalidRects initial_rect; + 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 // propagated correctly. class CapturerCallback2 { public: - explicit CapturerCallback2(const SkRegion& expected_dirty_region) - : expected_dirty_region_(expected_dirty_region) { } + explicit CapturerCallback2(const InvalidRects& expected_dirty_rects) + : expected_dirty_rects_(expected_dirty_rects) { } void CaptureDoneCallback(scoped_refptr<CaptureData> capture_data); protected: - SkRegion expected_dirty_region_; + InvalidRects expected_dirty_rects_; private: DISALLOW_COPY_AND_ASSIGN(CapturerCallback2); @@ -69,7 +70,7 @@ void CapturerCallback2::CaptureDoneCallback( int width = CGDisplayPixelsWide(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(height, capture_data->size().height()); const DataPlanes &planes = capture_data->data_planes(); @@ -88,13 +89,13 @@ TEST_F(CapturerMacTest, Capture) { SCOPED_TRACE(""); // Check that we get an initial full-screen updated. CapturerCallback1 callback1; - capturer_->CaptureInvalidRegion( + capturer_->CaptureInvalidRects( NewCallback(&callback1, &CapturerCallback1::CaptureDoneCallback)); // Check that subsequent dirty rects are propagated correctly. AddDirtyRect(); - CapturerCallback2 callback2(region_); - capturer_->InvalidateRegion(region_); - capturer_->CaptureInvalidRegion( + CapturerCallback2 callback2(rects_); + capturer_->InvalidateRects(rects_); + capturer_->CaptureInvalidRects( NewCallback(&callback2, &CapturerCallback2::CaptureDoneCallback)); } @@ -102,14 +103,13 @@ TEST_F(CapturerMacTest, Capture) { namespace gfx { -std::ostream& operator<<(std::ostream& out, const SkRegion& region) { - out << "SkRegion("; - for (SkRegion::Iterator i(region); !i.done(); i.next()) { - const SkIRect& r = i.rect(); - out << "(" << r.fLeft << "," << r.fTop << "," - << r.fRight << "," << r.fBottom << ")"; +std::ostream& operator<<(std::ostream& out, + const remoting::InvalidRects& rects) { + for (remoting::InvalidRects::const_iterator i = rects.begin(); + i != rects.end(); + ++i) { + out << *i << std::endl; } - out << ")"; return out; } diff --git a/remoting/host/capturer_win.cc b/remoting/host/capturer_win.cc index 1fb8b8a..b5fe81e 100644 --- a/remoting/host/capturer_win.cc +++ b/remoting/host/capturer_win.cc @@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "remoting/host/capturer_helper.h" #include "remoting/host/differ.h" +#include "ui/gfx/rect.h" namespace remoting { @@ -26,12 +27,11 @@ class CapturerGdi : public Capturer { // Capturer interface. virtual void ScreenConfigurationChanged() OVERRIDE; virtual media::VideoFrame::Format pixel_format() const OVERRIDE; - virtual void ClearInvalidRegion() OVERRIDE; - virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; + virtual void ClearInvalidRects() OVERRIDE; + virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE; virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; virtual void InvalidateFullScreen() OVERRIDE; - virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback) - OVERRIDE; + virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE; virtual const gfx::Size& size_most_recent() const OVERRIDE; private: @@ -60,9 +60,9 @@ class CapturerGdi : public Capturer { // allocated for that buffer. void ReallocateBuffer(int buffer_index, const gfx::Size& size); - void CalculateInvalidRegion(); - void CaptureRegion(const SkRegion& region, - CaptureCompletedCallback* callback); + void CalculateInvalidRects(); + void CaptureRects(const InvalidRects& rects, + CaptureCompletedCallback* callback); void ReleaseBuffers(); // Generates an image in the current buffer. @@ -77,7 +77,7 @@ class CapturerGdi : public Capturer { // A thread-safe list of invalid rectangles, and the size of the most // recently captured screen. - CapturerHelper helper_; + CapturerHelper helper; // There are two buffers for the screen images, as required by Capturer. static const int kNumBuffers = 2; @@ -132,31 +132,31 @@ media::VideoFrame::Format CapturerGdi::pixel_format() const { return pixel_format_; } -void CapturerGdi::ClearInvalidRegion() { - helper_.ClearInvalidRegion(); +void CapturerGdi::ClearInvalidRects() { + helper.ClearInvalidRects(); } -void CapturerGdi::InvalidateRegion(const SkRegion& invalid_region) { - helper_.InvalidateRegion(invalid_region); +void CapturerGdi::InvalidateRects(const InvalidRects& inval_rects) { + helper.InvalidateRects(inval_rects); } void CapturerGdi::InvalidateScreen(const gfx::Size& size) { - helper_.InvalidateScreen(size); + helper.InvalidateScreen(size); } void CapturerGdi::InvalidateFullScreen() { - helper_.InvalidateFullScreen(); + helper.InvalidateFullScreen(); } -void CapturerGdi::CaptureInvalidRegion(CaptureCompletedCallback* callback) { - CalculateInvalidRegion(); - SkRegion invalid_region; - helper_.SwapInvalidRegion(&invalid_region); - CaptureRegion(invalid_region, callback); +void CapturerGdi::CaptureInvalidRects(CaptureCompletedCallback* callback) { + CalculateInvalidRects(); + InvalidRects inval_rects; + helper.SwapInvalidRects(inval_rects); + CaptureRects(inval_rects, callback); } const gfx::Size& CapturerGdi::size_most_recent() const { - return helper_.size_most_recent(); + return helper.size_most_recent(); } void CapturerGdi::ReleaseBuffers() { @@ -243,11 +243,11 @@ void CapturerGdi::ReallocateBuffer(int buffer_index, const gfx::Size& size) { bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight); } -void CapturerGdi::CalculateInvalidRegion() { +void CapturerGdi::CalculateInvalidRects() { CaptureImage(); const VideoFrameBuffer& current = buffers_[current_buffer_]; - if (helper_.IsCaptureFullScreen(current.size)) + if (helper.IsCaptureFullScreen(current.size)) capture_fullscreen_ = true; if (capture_fullscreen_) { @@ -282,14 +282,14 @@ void CapturerGdi::CalculateInvalidRegion() { current.bytes_per_pixel, current.bytes_per_row)); } - SkRegion region; - differ_->CalcDirtyRegion(prev.data, current.data, ®ion); + InvalidRects rects; + differ_->CalcDirtyRects(prev.data, current.data, &rects); - InvalidateRegion(region); + InvalidateRects(rects); } -void CapturerGdi::CaptureRegion(const SkRegion& region, - CaptureCompletedCallback* callback) { +void CapturerGdi::CaptureRects(const InvalidRects& rects, + CaptureCompletedCallback* callback) { scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); const VideoFrameBuffer& buffer = buffers_[current_buffer_]; @@ -302,9 +302,9 @@ void CapturerGdi::CaptureRegion(const SkRegion& region, scoped_refptr<CaptureData> data(new CaptureData(planes, buffer.size, 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); } diff --git a/remoting/host/differ.cc b/remoting/host/differ.cc index 582521c..d5e618a 100644 --- a/remoting/host/differ.cc +++ b/remoting/host/differ.cc @@ -26,12 +26,12 @@ Differ::Differ(int width, int height, int bpp, int stride) { Differ::~Differ() {} -void Differ::CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer, - SkRegion* region) { - if (!region) { +void Differ::CalcDirtyRects(const void* prev_buffer, const void* curr_buffer, + InvalidRects* rects) { + if (!rects) { return; } - region->setEmpty(); + rects->clear(); if (!prev_buffer || !curr_buffer) { return; @@ -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 // 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) { @@ -131,9 +131,9 @@ DiffInfo Differ::DiffPartialBlock(const uint8* prev_buffer, return 0; } -void Differ::MergeBlocks(SkRegion* region) { - DCHECK(region); - region->setEmpty(); +void Differ::MergeBlocks(InvalidRects* rects) { + DCHECK(rects); + rects->clear(); uint8* diff_info_row_start = static_cast<uint8*>(diff_info_.get()); int diff_info_stride = diff_info_width_ * sizeof(DiffInfo); @@ -195,8 +195,7 @@ void Differ::MergeBlocks(SkRegion* region) { if (top + height > height_) { height = height_ - top; } - region->op(SkIRect::MakeXYWH(left, top, width, height), - SkRegion::kUnion_Op); + rects->insert(gfx::Rect(left, top, width, height)); } // Increment to next block in this row. diff --git a/remoting/host/differ.h b/remoting/host/differ.h index c46f57a..9903680 100644 --- a/remoting/host/differ.h +++ b/remoting/host/differ.h @@ -9,16 +9,13 @@ #include "base/basictypes.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 { 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 { public: // Create a differ that operates on bitmaps with the specified width, height @@ -31,22 +28,24 @@ class Differ { int bytes_per_pixel() { return bytes_per_pixel_; } int bytes_per_row() { return bytes_per_row_; } - // Given the previous and current screen buffer, calculate the dirty region - // that encloses all of the changed pixels in the new screen. - void CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer, - SkRegion* region); - - private: - // Allow tests to access our private parts. - friend class DifferTest; + // Given the previous and current screen buffer, calculate the set of + // rectangles that enclose all the changed pixels in the new screen. + void CalcDirtyRects(const void* prev_buffer, const void* curr_buffer, + InvalidRects* rects); // Identify all of the blocks that contain changed pixels. void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer); // After the dirty blocks have been identified, this routine merges adjacent - // blocks into a region. - // The goal is to minimize the region that covers the dirty blocks. - void MergeBlocks(SkRegion* region); + // blocks into larger rectangular units. + // The goal is to minimize the number of rects that cover the dirty blocks, + // 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 // to check is specified by the |width| and |height| values. diff --git a/remoting/host/differ_unittest.cc b/remoting/host/differ_unittest.cc index 6ddd722..23702a8 100644 --- a/remoting/host/differ_unittest.cc +++ b/remoting/host/differ_unittest.cc @@ -44,24 +44,6 @@ class DifferTest : public testing::Test { memset(buffer, 0, buffer_size_); } - // Here in DifferTest so that tests can access private methods of Differ. - void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer) { - differ_->MarkDirtyBlocks(prev_buffer, curr_buffer); - } - - void MergeBlocks(SkRegion* dirty) { - differ_->MergeBlocks(dirty); - } - - // Convenience method to count rectangles in a region. - int RegionRectCount(const SkRegion& region) { - int count = 0; - for(SkRegion::Iterator iter(region); !iter.done(); iter.next()) { - ++count; - } - return count; - } - // Convenience wrapper for Differ's DiffBlock that calculates the appropriate // offset to the start of the desired block. DiffInfo DiffBlock(int block_x, int block_y) { @@ -141,37 +123,29 @@ class DifferTest : public testing::Test { } } - // Verify that |region| contains a rectangle defined by |x|, |y|, |width| and - // |height|. + // Verify that the given dirty rect matches the expected |x|, |y|, |width| + // and |height|. // |x|, |y|, |width| and |height| are specified in block (not pixel) units. - bool CheckDirtyRegionContainsRect(const SkRegion& region, int x, int y, - int width, int height) { - SkIRect r = SkIRect::MakeXYWH(x * kBlockSize, y * kBlockSize, - width * kBlockSize, height * kBlockSize); - bool found = false; - for (SkRegion::Iterator i(region); !found && !i.done(); i.next()) { - found = (i.rect() == r); - } - return found; + void CheckDirtyRect(const InvalidRects& rects, int x, int y, + int width, int height) { + gfx::Rect r(x * kBlockSize, y * kBlockSize, + width * kBlockSize, height * kBlockSize); + EXPECT_TRUE(rects.find(r) != rects.end()); } // Mark the range of blocks specified and then verify that they are // merged correctly. // Only one rectangular region of blocks can be checked with this routine. - bool MarkBlocksAndCheckMerge(int x_origin, int y_origin, + void MarkBlocksAndCheckMerge(int x_origin, int y_origin, int width, int height) { ClearDiffInfo(); MarkBlocks(x_origin, y_origin, width, height); - SkRegion dirty; - MergeBlocks(&dirty); + scoped_ptr<InvalidRects> dirty(new InvalidRects()); + differ_->MergeBlocks(dirty.get()); - bool is_good = dirty.isRect(); - if (is_good) { - is_good = CheckDirtyRegionContainsRect(dirty, x_origin, y_origin, - width, height); - } - return is_good; + ASSERT_EQ(1UL, dirty->size()); + CheckDirtyRect(*dirty.get(), x_origin, y_origin, width, height); } // The differ class we're testing. @@ -222,7 +196,7 @@ TEST_F(DifferTest, MarkDirtyBlocks_All) { } } - MarkDirtyBlocks(prev_.get(), curr_.get()); + differ_->MarkDirtyBlocks(prev_.get(), curr_.get()); // Make sure each block is marked as dirty. for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { @@ -242,7 +216,7 @@ TEST_F(DifferTest, MarkDirtyBlocks_Sampling) { WriteBlockPixel(curr_.get(), 2, 1, 10, 10, 0xff00ff); WriteBlockPixel(curr_.get(), 0, 2, 10, 10, 0xff00ff); - MarkDirtyBlocks(prev_.get(), curr_.get()); + differ_->MarkDirtyBlocks(prev_.get(), curr_.get()); // Make sure corresponding blocks are updated. EXPECT_EQ(0, GetDiffInfo(0, 0)); @@ -310,7 +284,7 @@ TEST_F(DifferTest, Partial_FirstPixel) { } } - MarkDirtyBlocks(prev_.get(), curr_.get()); + differ_->MarkDirtyBlocks(prev_.get(), curr_.get()); // Make sure each block is marked as dirty. for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { @@ -333,7 +307,7 @@ TEST_F(DifferTest, Partial_BorderPixel) { WritePixel(curr_.get(), x, height_ - 1, 0xff00ff); } - MarkDirtyBlocks(prev_.get(), curr_.get()); + differ_->MarkDirtyBlocks(prev_.get(), curr_.get()); // Make sure last (partial) block in each row/column is marked as dirty. int x_last = GetDiffInfoWidth() - 2; @@ -369,10 +343,10 @@ TEST_F(DifferTest, MergeBlocks_Empty) { // +---+---+---+---+ ClearDiffInfo(); - SkRegion dirty; - MergeBlocks(&dirty); + scoped_ptr<InvalidRects> dirty(new InvalidRects()); + differ_->MergeBlocks(dirty.get()); - EXPECT_TRUE(dirty.isEmpty()); + EXPECT_EQ(0UL, dirty->size()); } TEST_F(DifferTest, MergeBlocks_SingleBlock) { @@ -381,8 +355,7 @@ TEST_F(DifferTest, MergeBlocks_SingleBlock) { // rect with the correct bounds. for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { - ASSERT_TRUE(MarkBlocksAndCheckMerge(x, y, 1, 1)) << "x: " << x - << "y: " << y; + MarkBlocksAndCheckMerge(x, y, 1, 1); } } } @@ -399,7 +372,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRow) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 1)); + MarkBlocksAndCheckMerge(0, 0, 2, 1); // +---+---+---+---+ // | | | | _ | @@ -410,7 +383,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRow) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 1)); + MarkBlocksAndCheckMerge(0, 1, 3, 1); // +---+---+---+---+ // | | | | _ | @@ -421,7 +394,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRow) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 2, 2, 1)); + MarkBlocksAndCheckMerge(1, 2, 2, 1); } TEST_F(DifferTest, MergeBlocks_BlockColumn) { @@ -436,7 +409,7 @@ TEST_F(DifferTest, MergeBlocks_BlockColumn) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 1, 2)); + MarkBlocksAndCheckMerge(0, 0, 1, 2); // +---+---+---+---+ // | | | | _ | @@ -447,7 +420,7 @@ TEST_F(DifferTest, MergeBlocks_BlockColumn) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 1, 2)); + MarkBlocksAndCheckMerge(1, 1, 1, 2); // +---+---+---+---+ // | | | X | _ | @@ -458,7 +431,7 @@ TEST_F(DifferTest, MergeBlocks_BlockColumn) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(2, 0, 1, 3)); + MarkBlocksAndCheckMerge(2, 0, 1, 3); } TEST_F(DifferTest, MergeBlocks_BlockRect) { @@ -473,7 +446,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRect) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 2)); + MarkBlocksAndCheckMerge(0, 0, 2, 2); // +---+---+---+---+ // | | | | _ | @@ -484,7 +457,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRect) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 2, 2)); + MarkBlocksAndCheckMerge(1, 1, 2, 2); // +---+---+---+---+ // | | X | X | _ | @@ -495,7 +468,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRect) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 0, 2, 3)); + MarkBlocksAndCheckMerge(1, 0, 2, 3); // +---+---+---+---+ // | | | | _ | @@ -506,7 +479,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRect) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 2)); + MarkBlocksAndCheckMerge(0, 1, 3, 2); // +---+---+---+---+ // | X | X | X | _ | @@ -517,7 +490,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRect) { // +---+---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ - ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 3, 3)); + MarkBlocksAndCheckMerge(0, 0, 3, 3); } // This tests marked regions that require more than 1 single dirty rect. @@ -525,7 +498,7 @@ TEST_F(DifferTest, MergeBlocks_BlockRect) { // may need to be updated if we modify how we merge blocks. TEST_F(DifferTest, MergeBlocks_MultiRect) { InitDiffer(kScreenWidth, kScreenHeight); - SkRegion dirty; + scoped_ptr<InvalidRects> dirty; // +---+---+---+---+ +---+---+---+ // | | X | | _ | | | 0 | | @@ -541,40 +514,40 @@ TEST_F(DifferTest, MergeBlocks_MultiRect) { MarkBlocks(0, 1, 1, 1); MarkBlocks(2, 2, 1, 1); - dirty.setEmpty(); - MergeBlocks(&dirty); + dirty.reset(new InvalidRects()); + differ_->MergeBlocks(dirty.get()); - ASSERT_EQ(3, RegionRectCount(dirty)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 0, 1, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1)); + ASSERT_EQ(3UL, dirty->size()); + CheckDirtyRect(*dirty.get(), 1, 0, 1, 1); + CheckDirtyRect(*dirty.get(), 0, 1, 1, 1); + CheckDirtyRect(*dirty.get(), 2, 2, 1, 1); // +---+---+---+---+ +---+---+---+ // | | | X | _ | | | | 0 | - // +---+---+---+---+ +---+---+---+ - // | X | X | X | _ | | 1 1 1 | - // +---+---+---+---+ => + + - // | X | X | X | _ | | 1 1 1 | + // +---+---+---+---+ +---+---+ + + // | X | X | X | _ | | 1 1 | 0 | + // +---+---+---+---+ => + + + + // | X | X | X | _ | | 1 1 | 0 | // +---+---+---+---+ +---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ ClearDiffInfo(); - MarkBlocks(2, 0, 1, 1); - MarkBlocks(0, 1, 3, 2); + MarkBlocks(2, 0, 1, 3); + MarkBlocks(0, 1, 2, 2); - dirty.setEmpty(); - MergeBlocks(&dirty); + dirty.reset(new InvalidRects()); + differ_->MergeBlocks(dirty.get()); - ASSERT_EQ(2, RegionRectCount(dirty)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 0, 1, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 3, 2)); + ASSERT_EQ(2UL, dirty->size()); + CheckDirtyRect(*dirty.get(), 2, 0, 1, 3); + CheckDirtyRect(*dirty.get(), 0, 1, 2, 2); // +---+---+---+---+ +---+---+---+ // | | | | _ | | | | | // +---+---+---+---+ +---+---+---+ // | X | | X | _ | | 0 | | 1 | // +---+---+---+---+ => + +---+ + - // | X | X | X | _ | | 2 | 2 | 2 | + // | X | X | X | _ | | 0 | 2 | 1 | // +---+---+---+---+ +---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ @@ -583,20 +556,20 @@ TEST_F(DifferTest, MergeBlocks_MultiRect) { MarkBlocks(2, 1, 1, 1); MarkBlocks(0, 2, 3, 1); - dirty.setEmpty(); - MergeBlocks(&dirty); + dirty.reset(new InvalidRects()); + differ_->MergeBlocks(dirty.get()); - ASSERT_EQ(3, RegionRectCount(dirty)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1)); + ASSERT_EQ(3UL, dirty->size()); + CheckDirtyRect(*dirty.get(), 0, 1, 1, 2); + CheckDirtyRect(*dirty.get(), 2, 1, 1, 2); + CheckDirtyRect(*dirty.get(), 1, 2, 1, 1); // +---+---+---+---+ +---+---+---+ // | X | X | X | _ | | 0 0 0 | // +---+---+---+---+ +---+---+---+ // | X | | X | _ | | 1 | | 2 | // +---+---+---+---+ => + +---+ + - // | X | X | X | _ | | 3 | 3 | 3 | + // | X | X | X | _ | | 1 | 3 | 2 | // +---+---+---+---+ +---+---+---+ // | _ | _ | _ | _ | // +---+---+---+---+ @@ -606,14 +579,14 @@ TEST_F(DifferTest, MergeBlocks_MultiRect) { MarkBlocks(2, 1, 1, 1); MarkBlocks(0, 2, 3, 1); - dirty.setEmpty(); - MergeBlocks(&dirty); + dirty.reset(new InvalidRects()); + differ_->MergeBlocks(dirty.get()); - ASSERT_EQ(4, RegionRectCount(dirty)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 3, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1)); + ASSERT_EQ(4UL, dirty->size()); + CheckDirtyRect(*dirty.get(), 0, 0, 3, 1); + CheckDirtyRect(*dirty.get(), 0, 1, 1, 2); + CheckDirtyRect(*dirty.get(), 2, 1, 1, 2); + CheckDirtyRect(*dirty.get(), 1, 2, 1, 1); // +---+---+---+---+ +---+---+---+ // | X | X | | _ | | 0 0 | | @@ -628,12 +601,12 @@ TEST_F(DifferTest, MergeBlocks_MultiRect) { MarkBlocks(0, 0, 2, 2); MarkBlocks(1, 2, 1, 1); - dirty.setEmpty(); - MergeBlocks(&dirty); + dirty.reset(new InvalidRects()); + differ_->MergeBlocks(dirty.get()); - ASSERT_EQ(2, RegionRectCount(dirty)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 2, 2)); - ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 2, 1, 1)); + ASSERT_EQ(2UL, dirty->size()); + CheckDirtyRect(*dirty.get(), 0, 0, 2, 2); + CheckDirtyRect(*dirty.get(), 1, 2, 1, 1); } } // namespace remoting diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index ec486c1..0ab8636f 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -26,11 +26,11 @@ class MockCapturer : public Capturer { MOCK_METHOD0(ScreenConfigurationChanged, void()); MOCK_CONST_METHOD0(pixel_format, media::VideoFrame::Format()); - MOCK_METHOD0(ClearInvalidRegion, void()); - MOCK_METHOD1(InvalidateRegion, void(const SkRegion& invalid_region)); + MOCK_METHOD0(ClearInvalidRects, void()); + MOCK_METHOD1(InvalidateRects, void(const InvalidRects& inval_rects)); MOCK_METHOD1(InvalidateScreen, void(const gfx::Size&)); 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&()); private: diff --git a/remoting/host/screen_recorder.cc b/remoting/host/screen_recorder.cc index ce982e6..1a05797 100644 --- a/remoting/host/screen_recorder.cc +++ b/remoting/host/screen_recorder.cc @@ -218,7 +218,7 @@ void ScreenRecorder::DoCapture() { // And finally perform one capture. capture_start_time_ = base::Time::Now(); - capturer()->CaptureInvalidRegion( + capturer()->CaptureInvalidRects( NewCallback(this, &ScreenRecorder::CaptureDoneCallback)); } @@ -365,7 +365,7 @@ void ScreenRecorder::DoEncode( TraceContext::tracer()->PrintString("DoEncode called"); // 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. VideoPacket* packet = new VideoPacket(); packet->set_flags(VideoPacket::LAST_PARTITION); diff --git a/remoting/host/screen_recorder_unittest.cc b/remoting/host/screen_recorder_unittest.cc index a1c4f13..69650ee 100644 --- a/remoting/host/screen_recorder_unittest.cc +++ b/remoting/host/screen_recorder_unittest.cc @@ -31,9 +31,13 @@ namespace remoting { namespace { -ACTION_P2(RunCallback, region, data) { - SkRegion& dirty_region = data->mutable_dirty_region(); - dirty_region.op(region, SkRegion::kUnion_Op); +ACTION_P2(RunCallback, rects, data) { + InvalidRects& dirty_rects = data->mutable_dirty_rects(); + 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); delete arg0; } @@ -103,7 +107,8 @@ class ScreenRecorderTest : public testing::Test { // This test mocks capturer, encoder and network layer to operate one recording // cycle. 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; for (int i = 0; i < DataPlanes::kPlaneCount; ++i) { planes.data[i] = reinterpret_cast<uint8*>(i); @@ -114,8 +119,8 @@ TEST_F(ScreenRecorderTest, OneRecordCycle) { EXPECT_CALL(capturer_, InvalidateFullScreen()); // First the capturer is called. - EXPECT_CALL(capturer_, CaptureInvalidRegion(NotNull())) - .WillOnce(RunCallback(update_region, data)); + EXPECT_CALL(capturer_, CaptureInvalidRects(NotNull())) + .WillOnce(RunCallback(update_rects, data)); // Expect the encoder be called. EXPECT_CALL(*encoder_, Encode(data, false, NotNull())) @@ -151,7 +156,8 @@ TEST_F(ScreenRecorderTest, OneRecordCycle) { // ScreenRecorder is instructed to come to a complete stop. We expect the stop // sequence to be executed successfully. 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; for (int i = 0; i < DataPlanes::kPlaneCount; ++i) { planes.data[i] = reinterpret_cast<uint8*>(i); @@ -163,8 +169,8 @@ TEST_F(ScreenRecorderTest, StartAndStop) { EXPECT_CALL(capturer_, InvalidateFullScreen()); // First the capturer is called. - EXPECT_CALL(capturer_, CaptureInvalidRegion(NotNull())) - .WillRepeatedly(RunCallback(update_region, data)); + EXPECT_CALL(capturer_, CaptureInvalidRects(NotNull())) + .WillRepeatedly(RunCallback(update_rects, data)); // Expect the encoder be called. EXPECT_CALL(*encoder_, Encode(data, false, NotNull())) diff --git a/remoting/host/x_server_pixel_buffer.cc b/remoting/host/x_server_pixel_buffer.cc index a830920..8bfd004 100644 --- a/remoting/host/x_server_pixel_buffer.cc +++ b/remoting/host/x_server_pixel_buffer.cc @@ -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_pixmap_) { XCopyArea(display_, root_window_, shm_pixmap_, shm_gc_, - rect.fLeft, rect.fTop, rect.width(), rect.height(), - rect.fLeft, rect.fTop); + rect.x(), rect.y(), rect.width(), rect.height(), + rect.x(), rect.y()); XSync(display_, False); } return reinterpret_cast<uint8*>(x_image_->data) + - rect.fTop * x_image_->bytes_per_line + - rect.fLeft * x_image_->bits_per_pixel / 8; + rect.y() * x_image_->bytes_per_line + + rect.x() * x_image_->bits_per_pixel / 8; } else { if (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); return reinterpret_cast<uint8*>(x_image_->data); } diff --git a/remoting/host/x_server_pixel_buffer.h b/remoting/host/x_server_pixel_buffer.h index 161beab..49012f1 100644 --- a/remoting/host/x_server_pixel_buffer.h +++ b/remoting/host/x_server_pixel_buffer.h @@ -9,7 +9,7 @@ #include "base/basictypes.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/extensions/XShm.h> @@ -38,7 +38,7 @@ class XServerPixelBuffer { // call to CaptureRect. // In the case where the full-screen data is captured by Synchronize(), this // 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 // to be valid between CaptureRect calls. diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 51b2973..325313b 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -167,9 +167,6 @@ 'remoting_jingle_glue', '../third_party/npapi/npapi.gyp:npapi', ], - 'include_dirs': [ - '../skia/config', - ], 'sources': [ 'host/plugin/host_plugin.cc', 'host/plugin/host_plugin.def', @@ -181,11 +178,6 @@ 'host/plugin/host_script_object.h', ], 'conditions': [ - ['OS=="win"', { - 'include_dirs': [ - '../third_party/skia/include/config', - ], - }], ['OS=="mac"', { 'mac_bundle': 1, 'xcode_settings': { @@ -300,9 +292,6 @@ # TODO(hclam): Enable VP8 in the build. #'third_party/on2/on2.gyp:vp8', ], - 'include_dirs': [ - '../skia/config', - ], 'export_dependent_settings': [ '../base/base.gyp:base', '../net/net.gyp:net', @@ -349,6 +338,7 @@ 'base/task_thread_proxy.h', 'base/tracer.cc', 'base/tracer.h', + 'base/types.h', 'base/util.cc', 'base/util.h', ], @@ -361,11 +351,6 @@ 'base/encoder_vp8.h', ], }], - ['OS=="win"', { - 'include_dirs': [ - '../third_party/skia/include/config', - ], - }], ], }, # end of target 'remoting_base' @@ -379,9 +364,6 @@ 'differ_block', '../crypto/crypto.gyp:crypto', ], - 'include_dirs': [ - '../skia/config', - ], 'sources': [ 'host/access_verifier.h', 'host/capturer.h', @@ -468,11 +450,6 @@ ], }, }], - ['OS=="win"', { - 'include_dirs': [ - '../third_party/skia/include/config', - ], - }], ['OS=="mac"', { 'sources': [ '../third_party/GTM/AppKit/GTMCarbonEvent.h', @@ -505,9 +482,6 @@ 'remoting_jingle_glue', 'remoting_protocol', ], - 'include_dirs': [ - '../skia/config', - ], 'sources': [ 'client/chromoting_client.cc', 'client/chromoting_client.h', @@ -527,13 +501,6 @@ 'client/rectangle_update_decoder.cc', 'client/rectangle_update_decoder.h', ], - 'conditions': [ - ['OS=="win"', { - 'include_dirs': [ - '../third_party/skia/include/config', - ], - }], - ], }, # end of target 'remoting_client' { @@ -547,9 +514,6 @@ '../base/base.gyp:base_i18n', '../media/media.gyp:media', ], - 'include_dirs': [ - '../skia/config', - ], 'sources': [ 'host/capturer_fake_ascii.cc', 'host/capturer_fake_ascii.h', @@ -566,13 +530,6 @@ '../base/test/mock_chrome_application_mac.mm', '../base/test/mock_chrome_application_mac.h', ], - 'conditions': [ - ['OS=="win"', { - 'include_dirs': [ - '../third_party/skia/include/config', - ], - }], - ], }, # end of target 'remoting_simple_host' { @@ -726,6 +683,9 @@ { 'target_name': 'differ_block', 'type': 'static_library', + 'include_dirs': [ + '..', + ], 'dependencies': [ '../media/media.gyp:cpu_features', ], @@ -745,6 +705,9 @@ { 'target_name': 'differ_block_sse2', 'type': 'static_library', + 'include_dirs': [ + '..', + ], 'conditions': [ [ 'os_posix == 1 and OS != "mac"', { 'cflags': [ @@ -791,7 +754,6 @@ ], 'include_dirs': [ '../testing/gmock/include', - '../skia/config', ], 'sources': [ 'base/auth_token_util_unittest.cc', @@ -868,11 +830,6 @@ 'base/encoder_vp8_unittest.cc', ], }], - ['OS=="win"', { - 'include_dirs': [ - '../third_party/skia/include/config', - ], - }], ], # end of 'conditions' }, # end of target 'remoting_unittests' ], # end of targets diff --git a/skia/ext/skia_utils_mac.h b/skia/ext/skia_utils_mac.h index bdf6c1f..70cf9ea 100644 --- a/skia/ext/skia_utils_mac.h +++ b/skia/ext/skia_utils_mac.h @@ -6,7 +6,7 @@ #define SKIA_EXT_SKIA_UTILS_MAC_H_ #pragma once -#include <ApplicationServices/ApplicationServices.h> +#include <CoreGraphics/CGColor.h> #include <vector> #include "third_party/skia/include/core/SkColor.h" |