diff options
author | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-03 04:50:01 +0000 |
---|---|---|
committer | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-03 04:50:01 +0000 |
commit | afed40644caaaadcf7ada29ea3654f811d4d229c (patch) | |
tree | ca95a2756ee49a020b04478d19462f3e819738f5 /ui | |
parent | 6e1ff302c03fec1d2627a38b3c1c97102fde9902 (diff) | |
download | chromium_src-afed40644caaaadcf7ada29ea3654f811d4d229c.zip chromium_src-afed40644caaaadcf7ada29ea3654f811d4d229c.tar.gz chromium_src-afed40644caaaadcf7ada29ea3654f811d4d229c.tar.bz2 |
Test that pixels are drawn to the screen
No-oped on Windows and use_webkit_compositor==1.
BUG=None
TEST=compositor_unittests --gtest_filter=LayerWithRealCompositorTest.DrawPixels
Review URL: http://codereview.chromium.org/8418036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108427 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gfx/compositor/compositor.h | 4 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_cc.cc | 4 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_cc.h | 1 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_gl.cc | 48 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_gl.h | 3 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_win.cc | 6 | ||||
-rw-r--r-- | ui/gfx/compositor/layer_unittest.cc | 20 | ||||
-rw-r--r-- | ui/gfx/compositor/test_compositor.cc | 3 | ||||
-rw-r--r-- | ui/gfx/compositor/test_compositor.h | 1 |
9 files changed, 90 insertions, 0 deletions
diff --git a/ui/gfx/compositor/compositor.h b/ui/gfx/compositor/compositor.h index 6096d0a..9343975 100644 --- a/ui/gfx/compositor/compositor.h +++ b/ui/gfx/compositor/compositor.h @@ -13,6 +13,7 @@ #include "ui/gfx/native_widget_types.h" #include "ui/gfx/size.h" +class SkBitmap; class SkCanvas; namespace gfx { class Point; @@ -127,6 +128,9 @@ 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. + virtual void ReadPixels(SkBitmap* bitmap) = 0; + // Notifies the compositor that the size of the widget that it is // drawing to has changed. void WidgetSizeChanged(const gfx::Size& size) { diff --git a/ui/gfx/compositor/compositor_cc.cc b/ui/gfx/compositor/compositor_cc.cc index 754b6a8..780007c 100644 --- a/ui/gfx/compositor/compositor_cc.cc +++ b/ui/gfx/compositor/compositor_cc.cc @@ -174,6 +174,10 @@ void CompositorCC::DrawTree() { host_.composite(); } +void CompositorCC::ReadPixels(SkBitmap* bitmap) { + NOTIMPLEMENTED(); +} + void CompositorCC::animateAndLayout(double frameBeginTime) { } diff --git a/ui/gfx/compositor/compositor_cc.h b/ui/gfx/compositor/compositor_cc.h index 1bd4b58..dcaba1e 100644 --- a/ui/gfx/compositor/compositor_cc.h +++ b/ui/gfx/compositor/compositor_cc.h @@ -95,6 +95,7 @@ class COMPOSITOR_EXPORT CompositorCC : public Compositor, virtual void OnWidgetSizeChanged() OVERRIDE; virtual void OnRootLayerChanged() OVERRIDE; virtual void DrawTree() OVERRIDE; + virtual void ReadPixels(SkBitmap* bitmap) OVERRIDE; // WebLayerTreeViewClient implementation. virtual void animateAndLayout(double frameBeginTime) OVERRIDE; diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc index c28195c..92ada06 100644 --- a/ui/gfx/compositor/compositor_gl.cc +++ b/ui/gfx/compositor/compositor_gl.cc @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" #include "base/threading/thread_restrictions.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkDevice.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkPoint.h" @@ -505,6 +506,53 @@ CompositorGL::~CompositorGL() { gl_context_ = NULL; } +void CompositorGL::ReadPixels(SkBitmap* bitmap) { + MakeCurrent(); + + bitmap->setConfig(SkBitmap::kARGB_8888_Config, + size().width(), + size().height()); + bitmap->allocPixels(); + SkAutoLockPixels lock(*bitmap); + unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); + + // Check that it's a tight pixel packing + DCHECK_EQ(bitmap->rowBytes(), + SkBitmap::ComputeRowBytes(bitmap->config(), bitmap->width())); + + GLint current_alignment = 0; + glGetIntegerv(GL_PACK_ALIGNMENT, ¤t_alignment); + glPixelStorei(GL_PACK_ALIGNMENT, 4); + glReadPixels(0, + 0, + size().width(), + size().height(), + GL_RGBA, + GL_UNSIGNED_BYTE, + pixels); + glPixelStorei(GL_PACK_ALIGNMENT, current_alignment); + + // Swizzle from RGBA to BGRA + size_t bitmap_size = 4 * size().width() * size().height(); + for(size_t i = 0; i < bitmap_size; i += 4) + std::swap(pixels[i], pixels[i + 2]); + + // Vertical flip to transform from GL co-ords + size_t row_size = 4 * size().width(); + scoped_array<unsigned char> tmp_row(new unsigned char[row_size]); + for(int row = 0; row < size().height() / 2; row++) { + memcpy(tmp_row.get(), + &pixels[row * row_size], + row_size); + memcpy(&pixels[row * row_size], + &pixels[bitmap_size - (row + 1) * row_size], + row_size); + memcpy(&pixels[bitmap_size - (row + 1) * row_size], + tmp_row.get(), + row_size); + } +} + void CompositorGL::MakeCurrent() { gl_context_->MakeCurrent(gl_surface_.get()); } diff --git a/ui/gfx/compositor/compositor_gl.h b/ui/gfx/compositor/compositor_gl.h index cc59c68..586e793 100644 --- a/ui/gfx/compositor/compositor_gl.h +++ b/ui/gfx/compositor/compositor_gl.h @@ -100,6 +100,9 @@ class COMPOSITOR_EXPORT CompositorGL : public Compositor { const gfx::Size& size); virtual ~CompositorGL(); + // Overridden from Compositor. + virtual void ReadPixels(SkBitmap* bitmap) OVERRIDE; + void MakeCurrent(); gfx::Size GetSize(); diff --git a/ui/gfx/compositor/compositor_win.cc b/ui/gfx/compositor/compositor_win.cc index 18c71c9..38bf536 100644 --- a/ui/gfx/compositor/compositor_win.cc +++ b/ui/gfx/compositor/compositor_win.cc @@ -105,6 +105,8 @@ class CompositorWin : public Compositor { virtual void Blur(const gfx::Rect& bounds) OVERRIDE; + virtual void ReadPixels(SkBitmap* bitmap) OVERRIDE; + protected: virtual void OnNotifyStart(bool clear) OVERRIDE; virtual void OnNotifyEnd() OVERRIDE; @@ -501,6 +503,10 @@ void CompositorWin::Blur(const gfx::Rect& bounds) { #endif } +void CompositorWin::ReadPixels(SkBitmap* bitmap) { + NOTIMPLEMENTED(); +} + void CompositorWin::OnWidgetSizeChanged() { dest_render_target_view_ = NULL; depth_stencil_buffer_ = NULL; diff --git a/ui/gfx/compositor/layer_unittest.cc b/ui/gfx/compositor/layer_unittest.cc index 9443ab0..402488c 100644 --- a/ui/gfx/compositor/layer_unittest.cc +++ b/ui/gfx/compositor/layer_unittest.cc @@ -183,12 +183,14 @@ class NullLayerDelegate : public LayerDelegate { #define MAYBE_DrawTree DISABLED_DrawTree #define MAYBE_Hierarchy DISABLED_Hierarchy #define MAYBE_HierarchyNoTexture DISABLED_HierarchyNoTexture +#define MAYBE_DrawPixels DISABLED_DrawPixels #else #define MAYBE_Delegate Delegate #define MAYBE_Draw Draw #define MAYBE_DrawTree DrawTree #define MAYBE_Hierarchy Hierarchy #define MAYBE_HierarchyNoTexture HierarchyNoTexture +#define MAYBE_DrawPixels DrawPixels #endif TEST_F(LayerWithRealCompositorTest, MAYBE_Draw) { @@ -713,4 +715,22 @@ TEST_F(LayerWithNullDelegateTest, Visibility) { #endif } +// Checks that pixels are actually drawn to the screen with a read back. +TEST_F(LayerWithRealCompositorTest, MAYBE_DrawPixels) { + scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED, + gfx::Rect(0, 0, 500, 500))); + DrawTree(layer.get()); + + SkBitmap bitmap; + GetCompositor()->ReadPixels(&bitmap); + + 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++) + is_all_red = is_all_red && (bitmap.getColor(x, y) == SK_ColorRED); + + EXPECT_TRUE(is_all_red); +} + } // namespace ui diff --git a/ui/gfx/compositor/test_compositor.cc b/ui/gfx/compositor/test_compositor.cc index 4bc6faa..c21a13e 100644 --- a/ui/gfx/compositor/test_compositor.cc +++ b/ui/gfx/compositor/test_compositor.cc @@ -48,6 +48,9 @@ void TestCompositor::DrawTree() { #endif } +void TestCompositor::ReadPixels(SkBitmap* bitmap) { +} + ui::Compositor* TestCompositor::Create(ui::CompositorDelegate* owner) { return new ui::TestCompositor(owner); } diff --git a/ui/gfx/compositor/test_compositor.h b/ui/gfx/compositor/test_compositor.h index 6472496..791ef05 100644 --- a/ui/gfx/compositor/test_compositor.h +++ b/ui/gfx/compositor/test_compositor.h @@ -27,6 +27,7 @@ class TestCompositor : public ui::Compositor { virtual void OnNotifyEnd() OVERRIDE; virtual void Blur(const gfx::Rect& bounds) OVERRIDE; virtual void DrawTree() OVERRIDE; + virtual void ReadPixels(SkBitmap* bitmap) OVERRIDE; // A simple factory that creates a test compositor with a given delegate static ui::Compositor* Create(ui::CompositorDelegate* owner); |