diff options
-rw-r--r-- | cc/layer_impl.cc | 5 | ||||
-rw-r--r-- | cc/layer_impl.h | 3 | ||||
-rw-r--r-- | cc/layer_tree_host.cc | 5 | ||||
-rw-r--r-- | cc/layer_tree_host.h | 4 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.cc | 26 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.h | 6 | ||||
-rw-r--r-- | cc/layer_tree_host_unittest.cc | 69 | ||||
-rw-r--r-- | cc/picture.h | 2 | ||||
-rw-r--r-- | cc/picture_layer_impl.cc | 4 | ||||
-rw-r--r-- | cc/picture_layer_impl.h | 3 | ||||
-rw-r--r-- | cc/picture_pile_impl.cc | 25 | ||||
-rw-r--r-- | cc/picture_pile_impl.h | 4 | ||||
-rw-r--r-- | cc/proxy.h | 6 | ||||
-rw-r--r-- | cc/single_thread_proxy.cc | 7 | ||||
-rw-r--r-- | cc/single_thread_proxy.h | 1 | ||||
-rw-r--r-- | cc/test/fake_proxy.cc | 5 | ||||
-rw-r--r-- | cc/test/fake_proxy.h | 1 | ||||
-rw-r--r-- | cc/thread_proxy.cc | 23 | ||||
-rw-r--r-- | cc/thread_proxy.h | 2 |
19 files changed, 199 insertions, 2 deletions
diff --git a/cc/layer_impl.cc b/cc/layer_impl.cc index c588fe2..9840eff 100644 --- a/cc/layer_impl.cc +++ b/cc/layer_impl.cc @@ -287,6 +287,11 @@ gfx::Rect LayerImpl::layerRectToContentRect(const gfx::RectF& layerRect) const return gfx::ToEnclosingRect(contentRect); } +skia::RefPtr<SkPicture> LayerImpl::getPicture() +{ + return skia::RefPtr<SkPicture>(); +} + std::string LayerImpl::indentString(int indent) { std::string str; diff --git a/cc/layer_impl.h b/cc/layer_impl.h index 2219cf7..8b43f9f 100644 --- a/cc/layer_impl.h +++ b/cc/layer_impl.h @@ -24,6 +24,7 @@ #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkImageFilter.h" +#include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/rect.h" #include "ui/gfx/rect_f.h" #include "ui/gfx/transform.h" @@ -288,6 +289,8 @@ public: gfx::Rect layerRectToContentRect(const gfx::RectF& layerRect) const; + virtual skia::RefPtr<SkPicture> getPicture(); + protected: LayerImpl(LayerTreeImpl* layerImpl, int); diff --git a/cc/layer_tree_host.cc b/cc/layer_tree_host.cc index 9a42c63..862cccd 100644 --- a/cc/layer_tree_host.cc +++ b/cc/layer_tree_host.cc @@ -890,4 +890,9 @@ void LayerTreeHost::setAnimationEventsRecursive(const AnimationEventsVector& eve setAnimationEventsRecursive(events, layer->children()[childIndex].get(), wallClockTime); } +skia::RefPtr<SkPicture> LayerTreeHost::capturePicture() +{ + return m_proxy->capturePicture(); +} + } // namespace cc diff --git a/cc/layer_tree_host.h b/cc/layer_tree_host.h index 664c92a..67ac48c 100644 --- a/cc/layer_tree_host.h +++ b/cc/layer_tree_host.h @@ -24,7 +24,9 @@ #include "cc/rate_limiter.h" #include "cc/rendering_stats.h" #include "cc/scoped_ptr_vector.h" +#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/rect.h" #if defined(COMPILER_GCC) @@ -199,6 +201,8 @@ public: AnimationRegistrar* animationRegistrar() const { return m_animationRegistrar.get(); } + skia::RefPtr<SkPicture> capturePicture(); + protected: LayerTreeHost(LayerTreeHostClient*, const LayerTreeSettings&); bool initialize(scoped_ptr<Thread> implThread); diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 9d42698..9c217b0 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -1709,4 +1709,30 @@ void LayerTreeHostImpl::animateScrollbarsRecursive(LayerImpl* layer, base::TimeT animateScrollbarsRecursive(layer->children()[i], time); } +// static +LayerImpl* LayerTreeHostImpl::getNonCompositedContentLayerRecursive(LayerImpl* layer) +{ + if (!layer) + return NULL; + + if (layer->drawsContent()) + return layer; + + for (LayerImpl::LayerList::const_iterator it = layer->children().begin(); + it != layer->children().end(); ++it) { + LayerImpl* nccr = getNonCompositedContentLayerRecursive(*it); + if (nccr) + return nccr; + } + + return NULL; +} + +skia::RefPtr<SkPicture> LayerTreeHostImpl::capturePicture() +{ + LayerTreeImpl* tree = pendingTree() ? pendingTree() : activeTree(); + LayerImpl* layer = getNonCompositedContentLayerRecursive(tree->RootLayer()); + return layer ? layer->getPicture() : skia::RefPtr<SkPicture>(); +} + } // namespace cc diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h index 5f46811..4091d48 100644 --- a/cc/layer_tree_host_impl.h +++ b/cc/layer_tree_host_impl.h @@ -17,7 +17,9 @@ #include "cc/render_pass_sink.h" #include "cc/renderer.h" #include "cc/tile_manager.h" +#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/rect.h" namespace cc { @@ -300,6 +302,8 @@ public: const PinchZoomViewport& pinchZoomViewport() const { return m_pinchZoomViewport; } + skia::RefPtr<SkPicture> capturePicture(); + protected: LayerTreeHostImpl(const LayerTreeSettings&, LayerTreeHostImplClient*, Proxy*); void activatePendingTree(); @@ -346,6 +350,8 @@ private: void dumpRenderSurfaces(std::string*, int indent, const LayerImpl*) const; + static LayerImpl* getNonCompositedContentLayerRecursive(LayerImpl* layer); + scoped_ptr<OutputSurface> m_outputSurface; scoped_ptr<ResourceProvider> m_resourceProvider; scoped_ptr<Renderer> m_renderer; diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc index de4035a..703217d 100644 --- a/cc/layer_tree_host_unittest.cc +++ b/cc/layer_tree_host_unittest.cc @@ -11,6 +11,7 @@ #include "cc/layer_tree_host_impl.h" #include "cc/layer_tree_impl.h" #include "cc/output_surface.h" +#include "cc/picture_layer.h" #include "cc/prioritized_resource.h" #include "cc/single_thread_proxy.h" #include "cc/test/fake_content_layer.h" @@ -24,10 +25,12 @@ #include "cc/resource_update_queue.h" #include "cc/test/occlusion_tracker_test_common.h" #include "cc/timing_function.h" +#include "skia/ext/refptr.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" +#include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/point_conversions.h" #include "ui/gfx/size_conversions.h" #include "ui/gfx/vector2d_conversions.h" @@ -2019,5 +2022,71 @@ TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndSoftwareContent) EXPECT_EQ(0u, host->settings().maxPartialTextureUpdates); } +class LayerTreeHostTestCapturePicture : public LayerTreeHostTest { +public: + LayerTreeHostTestCapturePicture() + : m_bounds(gfx::Size(100, 100)) + , m_layer(PictureLayer::create(&m_contentClient)) + { + m_settings.implSidePainting = true; + } + + class FillRectContentLayerClient : public ContentLayerClient { + public: + virtual void paintContents(SkCanvas* canvas, const gfx::Rect& clip, gfx::RectF& opaque) OVERRIDE + { + SkPaint paint; + paint.setColor(SK_ColorGREEN); + + SkRect rect = SkRect::MakeWH(canvas->getDeviceSize().width(), canvas->getDeviceSize().height()); + opaque = gfx::RectF(rect.width(), rect.height()); + canvas->drawRect(rect, paint); + } + }; + + virtual void beginTest() OVERRIDE + { + m_layer->setIsDrawable(true); + m_layer->setBounds(m_bounds); + m_layerTreeHost->setViewportSize(m_bounds, m_bounds); + m_layerTreeHost->setRootLayer(m_layer); + + EXPECT_TRUE(m_layerTreeHost->initializeRendererIfNeeded()); + postSetNeedsCommitToMainThread(); + } + + virtual void didCommitAndDrawFrame() OVERRIDE + { + m_picture = m_layerTreeHost->capturePicture(); + endTest(); + } + + virtual void afterTest() OVERRIDE + { + EXPECT_EQ(m_bounds, gfx::Size(m_picture->width(), m_picture->height())); + + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_bounds.width(), m_bounds.height()); + bitmap.allocPixels(); + bitmap.eraseARGB(0, 0, 0, 0); + SkCanvas canvas(bitmap); + + m_picture->draw(&canvas); + + bitmap.lockPixels(); + SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); + EXPECT_EQ(SK_ColorGREEN, pixels[0]); + bitmap.unlockPixels(); + } + +private: + gfx::Size m_bounds; + FillRectContentLayerClient m_contentClient; + scoped_refptr<PictureLayer> m_layer; + skia::RefPtr<SkPicture> m_picture; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestCapturePicture); + } // namespace } // namespace cc diff --git a/cc/picture.h b/cc/picture.h index 4672c36..cee8b89 100644 --- a/cc/picture.h +++ b/cc/picture.h @@ -37,7 +37,7 @@ public: void Record(ContentLayerClient*, RenderingStats&); // Has Record() been called yet? - bool HasRecording() const { return picture_.get(); } + bool HasRecording() const { return picture_.get() != NULL; } // Apply this contents scale and raster the content rect into the canvas. void Raster(SkCanvas* canvas, gfx::Rect content_rect, float contents_scale); diff --git a/cc/picture_layer_impl.cc b/cc/picture_layer_impl.cc index e4c113a..5a6f111 100644 --- a/cc/picture_layer_impl.cc +++ b/cc/picture_layer_impl.cc @@ -192,6 +192,10 @@ void PictureLayerImpl::calculateContentsScale( gfx::ScaleSize(bounds(), max_contents_scale, max_contents_scale)); } +skia::RefPtr<SkPicture> PictureLayerImpl::getPicture() { + return pile_->GetFlattenedPicture(); +} + scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling, gfx::Rect rect) { TileManager* tile_manager = layerTreeImpl()->tile_manager(); diff --git a/cc/picture_layer_impl.h b/cc/picture_layer_impl.h index 60e2c8d..94c1ac3 100644 --- a/cc/picture_layer_impl.h +++ b/cc/picture_layer_impl.h @@ -10,6 +10,8 @@ #include "cc/picture_layer_tiling_set.h" #include "cc/picture_pile_impl.h" #include "cc/scoped_ptr_vector.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkPicture.h" namespace cc { @@ -35,6 +37,7 @@ public: float* contents_scale_x, float* contents_scale_y, gfx::Size* content_bounds) OVERRIDE; + virtual skia::RefPtr<SkPicture> getPicture() OVERRIDE; // PictureLayerTilingClient overrides. virtual scoped_refptr<Tile> CreateTile(PictureLayerTiling*, diff --git a/cc/picture_pile_impl.cc b/cc/picture_pile_impl.cc index 571dcc6..cb4ff2b 100644 --- a/cc/picture_pile_impl.cc +++ b/cc/picture_pile_impl.cc @@ -97,4 +97,29 @@ void PicturePileImpl::GatherPixelRefs( } } +skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() { + TRACE_EVENT0("cc", "PicturePileImpl::GetFlattenedPicture"); + + gfx::Rect layer_rect; + for (PicturePile::Pile::const_iterator i = pile_.begin(); + i != pile_.end(); ++i) { + layer_rect.Union((*i)->LayerRect()); + } + + skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); + if (layer_rect.IsEmpty()) + return picture; + + SkCanvas* canvas = picture->beginRecording( + layer_rect.width(), + layer_rect.height(), + SkPicture::kUsePathBoundsForClip_RecordingFlag); + + RenderingStats stats; + Raster(canvas, layer_rect, 1.0, &stats); + picture->endRecording(); + + return picture; +} + } // namespace cc diff --git a/cc/picture_pile_impl.h b/cc/picture_pile_impl.h index b20d2c9..9418e90 100644 --- a/cc/picture_pile_impl.h +++ b/cc/picture_pile_impl.h @@ -15,6 +15,8 @@ #include "cc/picture.h" #include "cc/picture_pile.h" #include "cc/scoped_ptr_vector.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/rect.h" namespace cc { @@ -41,6 +43,8 @@ public: void GatherPixelRefs(const gfx::Rect&, std::list<skia::LazyPixelRef*>&); + skia::RefPtr<SkPicture> GetFlattenedPicture(); + private: friend class PicturePile; @@ -7,9 +7,11 @@ #include "base/basictypes.h" #include "base/logging.h" -#include "base/time.h" #include "base/memory/scoped_ptr.h" +#include "base/time.h" #include "cc/cc_export.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkPicture.h" namespace gfx { class Rect; @@ -96,6 +98,8 @@ public: virtual void acquireLayerTextures() = 0; + virtual skia::RefPtr<SkPicture> capturePicture() = 0; + // Testing hooks virtual bool commitPendingForTesting() = 0; diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc index 33a3f58..9cccd0ff 100644 --- a/cc/single_thread_proxy.cc +++ b/cc/single_thread_proxy.cc @@ -398,4 +398,11 @@ bool SingleThreadProxy::commitPendingForTesting() return false; } +skia::RefPtr<SkPicture> SingleThreadProxy::capturePicture() +{ + // Requires impl-side painting, which is only supported in threaded compositing. + NOTREACHED(); + return skia::RefPtr<SkPicture>(); +} + } // namespace cc diff --git a/cc/single_thread_proxy.h b/cc/single_thread_proxy.h index 5e0a92a..b4e1ad9 100644 --- a/cc/single_thread_proxy.h +++ b/cc/single_thread_proxy.h @@ -45,6 +45,7 @@ public: virtual void acquireLayerTextures() OVERRIDE { } virtual void forceSerializeOnSwapBuffers() OVERRIDE; virtual bool commitPendingForTesting() OVERRIDE; + virtual skia::RefPtr<SkPicture> capturePicture() OVERRIDE; // LayerTreeHostImplClient implementation virtual void didLoseOutputSurfaceOnImplThread() OVERRIDE { } diff --git a/cc/test/fake_proxy.cc b/cc/test/fake_proxy.cc index 8b6315a..df382b8 100644 --- a/cc/test/fake_proxy.cc +++ b/cc/test/fake_proxy.cc @@ -61,4 +61,9 @@ bool FakeProxy::commitPendingForTesting() return false; } +skia::RefPtr<SkPicture> FakeProxy::capturePicture() +{ + return skia::RefPtr<SkPicture>(); +} + } // namespace cc diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h index e28ab33..6951a6c 100644 --- a/cc/test/fake_proxy.h +++ b/cc/test/fake_proxy.h @@ -38,6 +38,7 @@ public: virtual size_t maxPartialTextureUpdates() const OVERRIDE; virtual void acquireLayerTextures() OVERRIDE { } virtual bool commitPendingForTesting() OVERRIDE; + virtual skia::RefPtr<SkPicture> capturePicture() OVERRIDE; virtual RendererCapabilities& rendererCapabilities(); void setMaxPartialTextureUpdates(size_t); diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc index 68bb890..6979a15 100644 --- a/cc/thread_proxy.cc +++ b/cc/thread_proxy.cc @@ -1017,4 +1017,27 @@ void ThreadProxy::commitPendingOnImplThreadForTesting(CommitPendingRequest* requ request->completion.signal(); } +skia::RefPtr<SkPicture> ThreadProxy::capturePicture() +{ + DCHECK(isMainThread()); + CompletionEvent completion; + skia::RefPtr<SkPicture> picture; + { + DebugScopedSetMainThreadBlocked mainThreadBlocked(this); + Proxy::implThread()->postTask(base::Bind(&ThreadProxy::capturePictureOnImplThread, + m_implThreadWeakPtr, + &completion, + &picture)); + completion.wait(); + } + return picture; +} + +void ThreadProxy::capturePictureOnImplThread(CompletionEvent* completion, skia::RefPtr<SkPicture>* picture) +{ + DCHECK(isImplThread()); + *picture = m_layerTreeHostImpl->capturePicture(); + completion->signal(); +} + } // namespace cc diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h index 39bbb16..500ee1c 100644 --- a/cc/thread_proxy.h +++ b/cc/thread_proxy.h @@ -54,6 +54,7 @@ public: virtual void acquireLayerTextures() OVERRIDE; virtual void forceSerializeOnSwapBuffers() OVERRIDE; virtual bool commitPendingForTesting() OVERRIDE; + virtual skia::RefPtr<SkPicture> capturePicture() OVERRIDE; // LayerTreeHostImplClient implementation virtual void didLoseOutputSurfaceOnImplThread() OVERRIDE; @@ -133,6 +134,7 @@ private: void forceSerializeOnSwapBuffersOnImplThread(CompletionEvent*); void setNeedsForcedCommitOnImplThread(); void commitPendingOnImplThreadForTesting(CommitPendingRequest* request); + void capturePictureOnImplThread(CompletionEvent*, skia::RefPtr<SkPicture>*); // Accessed on main thread only. bool m_animateRequested; // Set only when setNeedsAnimate is called. |