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> {
// compositing.
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.
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
// drawing to has changed.
......
......@@ -191,14 +191,21 @@ void CompositorCC::DrawTree() {
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,
size().width(), size().height());
bounds.width(), bounds.height());
bitmap->allocPixels();
SkAutoLockPixels lock_image(*bitmap);
unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
if (host_.compositeAndReadback(pixels, gfx::Rect(size()))) {
SwizzleRGBAToBGRAAndFlip(pixels, size());
if (host_.compositeAndReadback(pixels,
gfx::Rect(new_origin, bounds.size()))) {
SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
return true;
}
return false;
......
......@@ -100,7 +100,7 @@ class COMPOSITOR_EXPORT CompositorCC
virtual void OnWidgetSizeChanged() OVERRIDE;
virtual void OnRootLayerChanged() OVERRIDE;
virtual void DrawTree() OVERRIDE;
virtual bool ReadPixels(SkBitmap* bitmap) OVERRIDE;
virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) OVERRIDE;
// WebLayerTreeViewClient implementation.
virtual void animateAndLayout(double frameBeginTime);
......
......@@ -558,12 +558,15 @@ CompositorGL::~CompositorGL() {
gl_context_ = NULL;
}
bool CompositorGL::ReadPixels(SkBitmap* bitmap) {
bool CompositorGL::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
MakeCurrent();
if (bounds.right() > size().width() || bounds.bottom() > size().height())
return false;
bitmap->setConfig(SkBitmap::kARGB_8888_Config,
size().width(),
size().height());
bounds.width(),
bounds.height());
bitmap->allocPixels();
SkAutoLockPixels lock(*bitmap);
unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
......@@ -575,16 +578,18 @@ bool CompositorGL::ReadPixels(SkBitmap* bitmap) {
GLint current_alignment = 0;
glGetIntegerv(GL_PACK_ALIGNMENT, &current_alignment);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(0,
0,
size().width(),
size().height(),
// Flip vertically to convert to OpenGL coordinates.
glReadPixels(bounds.x(),
size().height() - bounds.y() - bounds.height(),
bounds.width(),
bounds.height(),
GL_RGBA,
GL_UNSIGNED_BYTE,
pixels);
glPixelStorei(GL_PACK_ALIGNMENT, current_alignment);
SwizzleRGBAToBGRAAndFlip(pixels, size());
SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
return true;
}
......
......@@ -102,7 +102,7 @@ class COMPOSITOR_EXPORT CompositorGL : public Compositor {
virtual ~CompositorGL();
// Overridden from Compositor.
virtual bool ReadPixels(SkBitmap* bitmap) OVERRIDE;
virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) OVERRIDE;
void MakeCurrent();
gfx::Size GetSize();
......
......@@ -105,7 +105,7 @@ class CompositorWin : public Compositor {
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:
virtual void OnNotifyStart(bool clear) OVERRIDE;
......@@ -503,7 +503,7 @@ void CompositorWin::Blur(const gfx::Rect& bounds) {
#endif
}
bool CompositorWin::ReadPixels(SkBitmap* bitmap) {
bool CompositorWin::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
NOTIMPLEMENTED();
return false;
}
......
......@@ -170,6 +170,11 @@ class LayerWithRealCompositorTest : public testing::Test {
GetCompositor()->Draw(false);
}
bool ReadPixels(SkBitmap* bitmap) {
return GetCompositor()->ReadPixels(bitmap,
gfx::Rect(GetCompositor()->size()));
}
void RunPendingMessages() {
MessageLoopForUI::current()->RunAllPending();
}
......@@ -1088,16 +1093,24 @@ TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
TEST_F(LayerWithRealCompositorTest, MAYBE_DrawPixels) {
scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
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());
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());
SkAutoLockPixels lock(bitmap);
bool is_all_red = true;
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);
EXPECT_TRUE(is_all_red);
......@@ -1223,14 +1236,14 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) {
l11->Add(l21.get());
l0->Add(l12.get());
DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap));
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img1);
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
l0->MoveToFront(l11.get());
DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap));
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img2);
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
......@@ -1238,21 +1251,21 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) {
// l11 is already at the front, should have no effect.
l0->MoveToFront(l11.get());
DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap));
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
// l11 is already at the front, should have no effect.
l0->MoveAbove(l11.get(), l12.get());
DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap));
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
// should restore to original configuration
l0->MoveAbove(l12.get(), l11.get());
DrawTree(l0.get());
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap));
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
}
......@@ -1275,7 +1288,7 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_Opacity) {
l0->Add(l11.get());
DrawTree(l0.get());
SkBitmap bitmap;
ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap));
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img);
EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img));
......
......@@ -48,7 +48,7 @@ void TestCompositor::DrawTree() {
#endif
}
bool TestCompositor::ReadPixels(SkBitmap* bitmap) {
bool TestCompositor::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
return false;
}
......
......@@ -27,7 +27,7 @@ class TestCompositor : public ui::Compositor {
virtual void OnNotifyEnd() OVERRIDE;
virtual void Blur(const gfx::Rect& bounds) 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
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