Commit d86e97e3 authored by pkotwicz@chromium.org's avatar pkotwicz@chromium.org

Adds a bounds parameter to ui::Compositor::ReadPixels

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=110783

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110924 0039d316-1c4b-4281-b951-d872f2087c98
parent 976f356d
...@@ -136,9 +136,10 @@ class COMPOSITOR_EXPORT Compositor : public base::RefCounted<Compositor> { ...@@ -136,9 +136,10 @@ class COMPOSITOR_EXPORT Compositor : public base::RefCounted<Compositor> {
// compositing. // compositing.
void Draw(bool force_clear); void Draw(bool force_clear);
// Reads the contents of the last rendered frame into the given bitmap. // Reads the region |bounds| of the contents of the last rendered frame
// into the given bitmap.
// Returns false if the pixels could not be read. // Returns false if the pixels could not be read.
virtual bool ReadPixels(SkBitmap* bitmap) = 0; virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) = 0;
// Notifies the compositor that the size of the widget that it is // Notifies the compositor that the size of the widget that it is
// drawing to has changed. // drawing to has changed.
......
...@@ -191,14 +191,21 @@ void CompositorCC::DrawTree() { ...@@ -191,14 +191,21 @@ void CompositorCC::DrawTree() {
host_.composite(); host_.composite();
} }
bool CompositorCC::ReadPixels(SkBitmap* bitmap) { bool CompositorCC::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
if (bounds.right() > size().width() || bounds.bottom() > size().height())
return false;
// Convert to OpenGL coordinates.
gfx::Point new_origin(bounds.x(),
size().height() - bounds.height() - bounds.y());
bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmap->setConfig(SkBitmap::kARGB_8888_Config,
size().width(), size().height()); bounds.width(), bounds.height());
bitmap->allocPixels(); bitmap->allocPixels();
SkAutoLockPixels lock_image(*bitmap); SkAutoLockPixels lock_image(*bitmap);
unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
if (host_.compositeAndReadback(pixels, gfx::Rect(size()))) { if (host_.compositeAndReadback(pixels,
SwizzleRGBAToBGRAAndFlip(pixels, size()); gfx::Rect(new_origin, bounds.size()))) {
SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
return true; return true;
} }
return false; return false;
......
...@@ -100,7 +100,7 @@ class COMPOSITOR_EXPORT CompositorCC ...@@ -100,7 +100,7 @@ class COMPOSITOR_EXPORT CompositorCC
virtual void OnWidgetSizeChanged() OVERRIDE; virtual void OnWidgetSizeChanged() OVERRIDE;
virtual void OnRootLayerChanged() OVERRIDE; virtual void OnRootLayerChanged() OVERRIDE;
virtual void DrawTree() OVERRIDE; virtual void DrawTree() OVERRIDE;
virtual bool ReadPixels(SkBitmap* bitmap) OVERRIDE; virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) OVERRIDE;
// WebLayerTreeViewClient implementation. // WebLayerTreeViewClient implementation.
virtual void animateAndLayout(double frameBeginTime); virtual void animateAndLayout(double frameBeginTime);
......
...@@ -558,12 +558,15 @@ CompositorGL::~CompositorGL() { ...@@ -558,12 +558,15 @@ CompositorGL::~CompositorGL() {
gl_context_ = NULL; gl_context_ = NULL;
} }
bool CompositorGL::ReadPixels(SkBitmap* bitmap) { bool CompositorGL::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
MakeCurrent(); MakeCurrent();
if (bounds.right() > size().width() || bounds.bottom() > size().height())
return false;
bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmap->setConfig(SkBitmap::kARGB_8888_Config,
size().width(), bounds.width(),
size().height()); bounds.height());
bitmap->allocPixels(); bitmap->allocPixels();
SkAutoLockPixels lock(*bitmap); SkAutoLockPixels lock(*bitmap);
unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
...@@ -575,16 +578,18 @@ bool CompositorGL::ReadPixels(SkBitmap* bitmap) { ...@@ -575,16 +578,18 @@ bool CompositorGL::ReadPixels(SkBitmap* bitmap) {
GLint current_alignment = 0; GLint current_alignment = 0;
glGetIntegerv(GL_PACK_ALIGNMENT, &current_alignment); glGetIntegerv(GL_PACK_ALIGNMENT, &current_alignment);
glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(0,
0, // Flip vertically to convert to OpenGL coordinates.
size().width(), glReadPixels(bounds.x(),
size().height(), size().height() - bounds.y() - bounds.height(),
bounds.width(),
bounds.height(),
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
pixels); pixels);
glPixelStorei(GL_PACK_ALIGNMENT, current_alignment); glPixelStorei(GL_PACK_ALIGNMENT, current_alignment);
SwizzleRGBAToBGRAAndFlip(pixels, size()); SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
return true; return true;
} }
......
...@@ -102,7 +102,7 @@ class COMPOSITOR_EXPORT CompositorGL : public Compositor { ...@@ -102,7 +102,7 @@ class COMPOSITOR_EXPORT CompositorGL : public Compositor {
virtual ~CompositorGL(); virtual ~CompositorGL();
// Overridden from Compositor. // Overridden from Compositor.
virtual bool ReadPixels(SkBitmap* bitmap) OVERRIDE; virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) OVERRIDE;
void MakeCurrent(); void MakeCurrent();
gfx::Size GetSize(); gfx::Size GetSize();
......
...@@ -105,7 +105,7 @@ class CompositorWin : public Compositor { ...@@ -105,7 +105,7 @@ class CompositorWin : public Compositor {
virtual void Blur(const gfx::Rect& bounds) OVERRIDE; virtual void Blur(const gfx::Rect& bounds) OVERRIDE;
virtual bool ReadPixels(SkBitmap* bitmap) OVERRIDE; virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) OVERRIDE;
protected: protected:
virtual void OnNotifyStart(bool clear) OVERRIDE; virtual void OnNotifyStart(bool clear) OVERRIDE;
...@@ -503,7 +503,7 @@ void CompositorWin::Blur(const gfx::Rect& bounds) { ...@@ -503,7 +503,7 @@ void CompositorWin::Blur(const gfx::Rect& bounds) {
#endif #endif
} }
bool CompositorWin::ReadPixels(SkBitmap* bitmap) { bool CompositorWin::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return false; return false;
} }
......
...@@ -170,6 +170,11 @@ class LayerWithRealCompositorTest : public testing::Test { ...@@ -170,6 +170,11 @@ class LayerWithRealCompositorTest : public testing::Test {
GetCompositor()->Draw(false); GetCompositor()->Draw(false);
} }
bool ReadPixels(SkBitmap* bitmap) {
return GetCompositor()->ReadPixels(bitmap,
gfx::Rect(GetCompositor()->size()));
}
void RunPendingMessages() { void RunPendingMessages() {
MessageLoopForUI::current()->RunAllPending(); MessageLoopForUI::current()->RunAllPending();
} }
...@@ -1088,16 +1093,24 @@ TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) { ...@@ -1088,16 +1093,24 @@ TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
TEST_F(LayerWithRealCompositorTest, MAYBE_DrawPixels) { TEST_F(LayerWithRealCompositorTest, MAYBE_DrawPixels) {
scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED, scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
gfx::Rect(0, 0, 500, 500))); gfx::Rect(0, 0, 500, 500)));
scoped_ptr<Layer> layer2(CreateColorLayer(SK_ColorBLUE,
gfx::Rect(0, 0, 500, 10)));
layer->Add(layer2.get());
DrawTree(layer.get()); DrawTree(layer.get());
SkBitmap bitmap; SkBitmap bitmap;
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); gfx::Size size = GetCompositor()->size();
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap,
gfx::Rect(0, 10,
size.width(), size.height() - 10)));
ASSERT_FALSE(bitmap.empty()); ASSERT_FALSE(bitmap.empty());
SkAutoLockPixels lock(bitmap); SkAutoLockPixels lock(bitmap);
bool is_all_red = true; bool is_all_red = true;
for (int x = 0; is_all_red && x < 500; x++) for (int x = 0; is_all_red && x < 500; x++)
for (int y = 0; is_all_red && y < 500; y++) for (int y = 0; is_all_red && y < 490; y++)
is_all_red = is_all_red && (bitmap.getColor(x, y) == SK_ColorRED); is_all_red = is_all_red && (bitmap.getColor(x, y) == SK_ColorRED);
EXPECT_TRUE(is_all_red); EXPECT_TRUE(is_all_red);
...@@ -1223,14 +1236,14 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) { ...@@ -1223,14 +1236,14 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) {
l11->Add(l21.get()); l11->Add(l21.get());
l0->Add(l12.get()); l0->Add(l12.get());
DrawTree(l0.get()); DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty()); ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img1); // WritePNGFile(bitmap, ref_img1);
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1)); EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
l0->MoveToFront(l11.get()); l0->MoveToFront(l11.get());
DrawTree(l0.get()); DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty()); ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img2); // WritePNGFile(bitmap, ref_img2);
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2)); EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
...@@ -1238,21 +1251,21 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) { ...@@ -1238,21 +1251,21 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) {
// l11 is already at the front, should have no effect. // l11 is already at the front, should have no effect.
l0->MoveToFront(l11.get()); l0->MoveToFront(l11.get());
DrawTree(l0.get()); DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty()); ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2)); EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
// l11 is already at the front, should have no effect. // l11 is already at the front, should have no effect.
l0->MoveAbove(l11.get(), l12.get()); l0->MoveAbove(l11.get(), l12.get());
DrawTree(l0.get()); DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty()); ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2)); EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
// should restore to original configuration // should restore to original configuration
l0->MoveAbove(l12.get(), l11.get()); l0->MoveAbove(l12.get(), l11.get());
DrawTree(l0.get()); DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty()); ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1)); EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
} }
...@@ -1275,7 +1288,7 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_Opacity) { ...@@ -1275,7 +1288,7 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_Opacity) {
l0->Add(l11.get()); l0->Add(l11.get());
DrawTree(l0.get()); DrawTree(l0.get());
SkBitmap bitmap; SkBitmap bitmap;
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty()); ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img); // WritePNGFile(bitmap, ref_img);
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img)); EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img));
......
...@@ -48,7 +48,7 @@ void TestCompositor::DrawTree() { ...@@ -48,7 +48,7 @@ void TestCompositor::DrawTree() {
#endif #endif
} }
bool TestCompositor::ReadPixels(SkBitmap* bitmap) { bool TestCompositor::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
return false; return false;
} }
......
...@@ -27,7 +27,7 @@ class TestCompositor : public ui::Compositor { ...@@ -27,7 +27,7 @@ class TestCompositor : public ui::Compositor {
virtual void OnNotifyEnd() OVERRIDE; virtual void OnNotifyEnd() OVERRIDE;
virtual void Blur(const gfx::Rect& bounds) OVERRIDE; virtual void Blur(const gfx::Rect& bounds) OVERRIDE;
virtual void DrawTree() OVERRIDE; virtual void DrawTree() OVERRIDE;
virtual bool ReadPixels(SkBitmap* bitmap) OVERRIDE; virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) OVERRIDE;
// A simple factory that creates a test compositor with a given delegate // A simple factory that creates a test compositor with a given delegate
static ui::Compositor* Create(ui::CompositorDelegate* owner); static ui::Compositor* Create(ui::CompositorDelegate* owner);
......
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