diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-24 06:45:36 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-24 06:45:36 +0000 |
commit | 0e5f714c8e7d908a44d6474cbf162b9862b895f0 (patch) | |
tree | c22fa14c45d91f2bf2b712b1cca5b3947edaaae0 /cc/output | |
parent | a8e55b1e8c3faef8b9cdd17d444f837773cb8b1c (diff) | |
download | chromium_src-0e5f714c8e7d908a44d6474cbf162b9862b895f0.zip chromium_src-0e5f714c8e7d908a44d6474cbf162b9862b895f0.tar.gz chromium_src-0e5f714c8e7d908a44d6474cbf162b9862b895f0.tar.bz2 |
cc: Add CopyAsBitmapRequest class to hold the readback callback.
Currently when you request an async copy of a layer as a bitmap, we
pass around the raw base::Callback. In order to add functionality to
the copy/readback mechanism, we need to pass along other parameters
such as a size to scale the copy to. Instead of passing along an
ever-growing list of parameters, wrap the base::Callback in a class
called CopyAsBitmapRequest. Then new parameters can be added to this
class.
No change in behaviour here, covered by existing tests.
R=piman
BUG=242571
Review URL: https://chromiumcodereview.appspot.com/15435003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201990 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/output')
-rw-r--r-- | cc/output/copy_output_request.cc | 30 | ||||
-rw-r--r-- | cc/output/copy_output_request.h | 45 | ||||
-rw-r--r-- | cc/output/direct_renderer.cc | 12 | ||||
-rw-r--r-- | cc/output/direct_renderer.h | 4 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 44 | ||||
-rw-r--r-- | cc/output/gl_renderer.h | 9 | ||||
-rw-r--r-- | cc/output/software_renderer.cc | 5 | ||||
-rw-r--r-- | cc/output/software_renderer.h | 2 |
8 files changed, 114 insertions, 37 deletions
diff --git a/cc/output/copy_output_request.cc b/cc/output/copy_output_request.cc new file mode 100644 index 0000000..437cce5 --- /dev/null +++ b/cc/output/copy_output_request.cc @@ -0,0 +1,30 @@ +// Copyright 2013 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 "cc/output/copy_output_request.h" + +#include "base/callback_helpers.h" +#include "base/logging.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace cc { + +CopyOutputRequest::CopyOutputRequest(const CopyAsBitmapCallback& callback) + : bitmap_callback_(callback) {} + +CopyOutputRequest::~CopyOutputRequest() { + SendEmptyResult(); +} + +void CopyOutputRequest::SendEmptyResult() { + if (!bitmap_callback_.is_null()) + base::ResetAndReturn(&bitmap_callback_).Run(scoped_ptr<SkBitmap>()); +} + +void CopyOutputRequest::SendBitmapResult(scoped_ptr<SkBitmap> bitmap) { + DCHECK(HasBitmapRequest()); + base::ResetAndReturn(&bitmap_callback_).Run(bitmap.Pass()); +} + +} // namespace cc diff --git a/cc/output/copy_output_request.h b/cc/output/copy_output_request.h new file mode 100644 index 0000000..d0ef48b --- /dev/null +++ b/cc/output/copy_output_request.h @@ -0,0 +1,45 @@ +// Copyright 2013 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 CC_OUTPUT_COPY_OUTPUT_REQUEST_H_ +#define CC_OUTPUT_COPY_OUTPUT_REQUEST_H_ + +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "cc/base/cc_export.h" + +class SkBitmap; + +namespace cc { + +class CC_EXPORT CopyOutputRequest { + public: + typedef base::Callback<void(scoped_ptr<SkBitmap>)> CopyAsBitmapCallback; + + static scoped_ptr<CopyOutputRequest> CreateBitmapRequest( + const CopyAsBitmapCallback& bitmap_callback) { + return make_scoped_ptr(new CopyOutputRequest(bitmap_callback)); + } + + ~CopyOutputRequest(); + + bool IsEmpty() const { return !HasBitmapRequest(); } + bool HasBitmapRequest() const { return !bitmap_callback_.is_null(); } + + void SendEmptyResult(); + void SendBitmapResult(scoped_ptr<SkBitmap> bitmap); + + bool Equals(const CopyOutputRequest& other) const { + return bitmap_callback_.Equals(other.bitmap_callback_); + } + + private: + explicit CopyOutputRequest(const CopyAsBitmapCallback& callback); + + CopyAsBitmapCallback bitmap_callback_; +}; + +} // namespace cc + +#endif // CC_OUTPUT_COPY_OUTPUT_REQUEST_H_ diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc index 429ac22..e2c17b8 100644 --- a/cc/output/direct_renderer.cc +++ b/cc/output/direct_renderer.cc @@ -11,6 +11,7 @@ #include "base/hash_tables.h" #include "base/metrics/histogram.h" #include "cc/base/math_util.h" +#include "cc/output/copy_output_request.h" #include "cc/quads/draw_quad.h" #include "ui/gfx/rect_conversions.h" #include "ui/gfx/transform.h" @@ -200,16 +201,19 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order) { BeginDrawingFrame(&frame); for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) { - DrawRenderPass(&frame, render_passes_in_draw_order->at(i)); + RenderPass* pass = render_passes_in_draw_order->at(i); + DrawRenderPass(&frame, pass); - const RenderPass* pass = frame.current_render_pass; - for (size_t i = 0; i < pass->copy_callbacks.size(); ++i) { + for (ScopedPtrVector<CopyOutputRequest>::iterator it = + pass->copy_requests.begin(); + it != pass->copy_requests.end(); + ++it) { if (i > 0) { // Doing a readback is destructive of our state on Mac, so make sure // we restore the state between readbacks. http://crbug.com/99393. UseRenderPass(&frame, pass); } - CopyCurrentRenderPassToBitmap(&frame, pass->copy_callbacks[i]); + CopyCurrentRenderPassToBitmap(&frame, pass->copy_requests.take(it)); } } FinishDrawingFrame(&frame); diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h index 7c37551..4baadee 100644 --- a/cc/output/direct_renderer.h +++ b/cc/output/direct_renderer.h @@ -112,11 +112,9 @@ class CC_EXPORT DirectRenderer : public Renderer { virtual void EnsureScissorTestEnabled() = 0; virtual void EnsureScissorTestDisabled() = 0; - typedef base::Callback<void(scoped_ptr<SkBitmap>)> - CopyRenderPassCallback; virtual void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - const CopyRenderPassCallback& callback) = 0; + scoped_ptr<CopyOutputRequest> request) = 0; ScopedPtrHashMap<RenderPass::Id, CachedResource> render_pass_textures_; ResourceProvider* resource_provider_; diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 15766c4..47a7cc0 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -20,6 +20,7 @@ #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/output/context_provider.h" +#include "cc/output/copy_output_request.h" #include "cc/output/geometry_binding.h" #include "cc/output/gl_frame_data.h" #include "cc/output/output_surface.h" @@ -94,7 +95,7 @@ const float kAntiAliasingEpsilon = 1.0f / 1024.0f; struct GLRenderer::PendingAsyncReadPixels { PendingAsyncReadPixels() : buffer(0) {} - CopyRenderPassCallback copy_callback; + scoped_ptr<CopyOutputRequest> copy_request; base::CancelableClosure finished_read_pixels_callback; unsigned buffer; @@ -227,9 +228,8 @@ void GLRenderer::InitializeGrContext() { GLRenderer::~GLRenderer() { while (!pending_async_read_pixels_.empty()) { - pending_async_read_pixels_.back()->finished_read_pixels_callback.Cancel(); - pending_async_read_pixels_.back()->copy_callback.Run( - scoped_ptr<SkBitmap>()); + PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back(); + pending_read->finished_read_pixels_callback.Cancel(); pending_async_read_pixels_.pop_back(); } @@ -1873,10 +1873,10 @@ void GLRenderer::EnsureScissorTestDisabled() { void GLRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - const CopyRenderPassCallback& callback) { + scoped_ptr<CopyOutputRequest> request) { GetFramebufferPixelsAsync(frame->current_render_pass->output_rect, frame->flipped_y, - callback); + request.Pass()); } void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { @@ -2095,15 +2095,13 @@ void GLRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) { AsyncGetFramebufferPixelsCleanupCallback()); } -void GLRenderer::GetFramebufferPixelsAsync(gfx::Rect rect, - bool flipped_y, - CopyRenderPassCallback callback) { - if (callback.is_null()) +void GLRenderer::GetFramebufferPixelsAsync( + gfx::Rect rect, bool flipped_y, scoped_ptr<CopyOutputRequest> request) { + DCHECK(!request->IsEmpty()); + if (request->IsEmpty()) return; - if (rect.IsEmpty()) { - callback.Run(scoped_ptr<SkBitmap>()); + if (rect.IsEmpty()) return; - } scoped_ptr<SkBitmap> bitmap(new SkBitmap); bitmap->setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); @@ -2118,11 +2116,10 @@ void GLRenderer::GetFramebufferPixelsAsync(gfx::Rect rect, &GLRenderer::PassOnSkBitmap, base::Unretained(this), base::Passed(&bitmap), - base::Passed(&lock), - callback); + base::Passed(&lock)); scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels); - pending_read->copy_callback = callback; + pending_read->copy_request = request.Pass(); pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), pending_read.Pass()); @@ -2257,7 +2254,10 @@ void GLRenderer::FinishedReadback( gfx::Size size, bool flipped_y) { DCHECK(!pending_async_read_pixels_.empty()); - DCHECK_EQ(source_buffer, pending_async_read_pixels_.back()->buffer); + + PendingAsyncReadPixels* current_read = pending_async_read_pixels_.back(); + // Make sure we service the readbacks in order. + DCHECK_EQ(source_buffer, current_read->buffer); uint8* src_pixels = NULL; @@ -2296,7 +2296,7 @@ void GLRenderer::FinishedReadback( // TODO(danakj): This can go away when synchronous readback is no more and its // contents can just move here. if (!cleanup_callback.is_null()) - cleanup_callback.Run(src_pixels != NULL); + cleanup_callback.Run(current_read->copy_request.Pass(), src_pixels != NULL); pending_async_read_pixels_.pop_back(); } @@ -2304,15 +2304,13 @@ void GLRenderer::FinishedReadback( void GLRenderer::PassOnSkBitmap( scoped_ptr<SkBitmap> bitmap, scoped_ptr<SkAutoLockPixels> lock, - const CopyRenderPassCallback& callback, + scoped_ptr<CopyOutputRequest> request, bool success) { - DCHECK(callback.Equals(pending_async_read_pixels_.back()->copy_callback)); + DCHECK(request->HasBitmapRequest()); lock.reset(); if (success) - callback.Run(bitmap.Pass()); - else - callback.Run(scoped_ptr<SkBitmap>()); + request->SendBitmapResult(bitmap.Pass()); } bool GLRenderer::GetFramebufferTexture(ScopedResource* texture, diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index b81ae04..d90b32f 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -97,7 +97,7 @@ class CC_EXPORT GLRenderer void GetFramebufferPixelsAsync(gfx::Rect rect, bool flipped_y, - CopyRenderPassCallback callback); + scoped_ptr<CopyOutputRequest> request); bool GetFramebufferTexture(ScopedResource* resource, gfx::Rect device_rect); void ReleaseRenderPassTextures(); @@ -116,7 +116,7 @@ class CC_EXPORT GLRenderer virtual void EnsureScissorTestDisabled() OVERRIDE; virtual void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - const CopyRenderPassCallback& callback) OVERRIDE; + scoped_ptr<CopyOutputRequest> request) OVERRIDE; virtual void FinishDrawingQuadList() OVERRIDE; private: @@ -193,7 +193,8 @@ class CC_EXPORT GLRenderer bool InitializeSharedObjects(); void CleanupSharedObjects(); - typedef base::Callback<void(bool success)> + typedef base::Callback<void(scoped_ptr<CopyOutputRequest> copy_request, + bool success)> AsyncGetFramebufferPixelsCleanupCallback; void DoGetFramebufferPixels( uint8* pixels, @@ -209,7 +210,7 @@ class CC_EXPORT GLRenderer void PassOnSkBitmap( scoped_ptr<SkBitmap> bitmap, scoped_ptr<SkAutoLockPixels> lock, - const CopyRenderPassCallback& callback, + scoped_ptr<CopyOutputRequest> request, bool success); void ReinitializeGrCanvas(); diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 3906ea8..4a337ff 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -9,6 +9,7 @@ #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "cc/output/compositor_frame_metadata.h" +#include "cc/output/copy_output_request.h" #include "cc/output/output_surface.h" #include "cc/output/software_output_device.h" #include "cc/quads/debug_border_draw_quad.h" @@ -435,7 +436,7 @@ void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame, void SoftwareRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - const CopyRenderPassCallback& callback) { + scoped_ptr<CopyOutputRequest> request) { gfx::Size render_pass_size = frame->current_render_pass->output_rect.size(); scoped_ptr<SkBitmap> bitmap(new SkBitmap); @@ -444,7 +445,7 @@ void SoftwareRenderer::CopyCurrentRenderPassToBitmap( render_pass_size.height()); current_canvas_->readPixels(bitmap.get(), 0, 0); - callback.Run(bitmap.Pass()); + request->SendBitmapResult(bitmap.Pass()); } void SoftwareRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) { diff --git a/cc/output/software_renderer.h b/cc/output/software_renderer.h index 271fe84..72a5052 100644 --- a/cc/output/software_renderer.h +++ b/cc/output/software_renderer.h @@ -62,7 +62,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { virtual void EnsureScissorTestDisabled() OVERRIDE; virtual void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - const CopyRenderPassCallback& callback) OVERRIDE; + scoped_ptr<CopyOutputRequest> request) OVERRIDE; private: SoftwareRenderer( |