summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-18 18:24:24 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-18 18:24:24 +0000
commit6389458704504692b4fdf2e5869ff4dbf1b66b5c (patch)
tree25b696fd0597fe55ad7fa2a1c1554007071761c9
parentcfa8f9d79c87ea20f0162af76acedc2a7e6cb5ab (diff)
downloadchromium_src-6389458704504692b4fdf2e5869ff4dbf1b66b5c.zip
chromium_src-6389458704504692b4fdf2e5869ff4dbf1b66b5c.tar.gz
chromium_src-6389458704504692b4fdf2e5869ff4dbf1b66b5c.tar.bz2
cc: Add ability to request copy of compositor output as a texture.
This adds the ability to request the compositor's output as a texture instead of requiring a readback to a SkBitmap on the cpu. This will allow the embedder to make a request for a texture and then scale or sample it without reading back the entire full-sized texture to the cpu. To readback successive frames will require constant commits at this time, but the mechanism could be extended to allow one main thread request to result in multiple copy result callbacks. This is tested by the LayerTreeHostPixelTestReadback tests. I've added a viewport offset, and surface expansion size, to all of the LayerTreeTest based pixel tests. This exposed a bug in the math for background filters when a viewport offset/surface expansion size is present, so this is fixed as well to make the tests pass (one line in GLRenderer::ApplyBackgroundFilters). Instead of having the CopyOutputRequest return a SkBitmap directly, or return a TextureMailbox directly (sometimes backed by a software bitmap), I've added a CopyOutputResult class to return with a reply from the compositor. This reply may be a texture (via a TextureMailbox) or a bitmap (via an SkBitmap). The embedder should be able to handle either one when it makes a request, unless its request forces a software-bitmap reply. The tests verify GLRenderer+general request, GLRenderer+forced software request, and SoftwareRenderer+general request. Adding the offset/expansion to the viewport/surface causes the offaxis background blur pixel test to become off-by-one in 5 pixels, requiring a rebaseline. R=enne, jamesr, piman BUG=242571 Review URL: https://chromiumcodereview.appspot.com/17018002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207037 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/cc_tests.gyp4
-rw-r--r--cc/layers/layer.cc20
-rw-r--r--cc/output/copy_output_request.cc31
-rw-r--r--cc/output/copy_output_request.h41
-rw-r--r--cc/output/copy_output_result.cc39
-rw-r--r--cc/output/copy_output_result.h55
-rw-r--r--cc/output/gl_renderer.cc177
-rw-r--r--cc/output/gl_renderer.h20
-rw-r--r--cc/quads/render_pass_unittest.cc3
-rw-r--r--cc/test/layer_tree_pixel_test.cc152
-rw-r--r--cc/test/layer_tree_pixel_test.h17
-rw-r--r--cc/test/pixel_test.cc80
-rw-r--r--cc/test/pixel_test.h5
-rw-r--r--cc/test/pixel_test_output_surface.cc21
-rw-r--r--cc/test/pixel_test_output_surface.h37
-rw-r--r--cc/test/pixel_test_software_output_device.cc15
-rw-r--r--cc/test/pixel_test_software_output_device.h26
-rw-r--r--cc/trees/layer_tree_host_pixeltest_filters.cc2
-rw-r--r--cc/trees/layer_tree_host_pixeltest_readback.cc275
-rw-r--r--cc/trees/layer_tree_host_unittest.cc28
21 files changed, 858 insertions, 192 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 67b1821..f64974a 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -163,6 +163,8 @@
'output/context_provider.h',
'output/copy_output_request.cc',
'output/copy_output_request.h',
+ 'output/copy_output_result.cc',
+ 'output/copy_output_result.h',
'output/delegated_frame_data.h',
'output/delegated_frame_data.cc',
'output/delegating_renderer.cc',
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index bb89d4e..ad10da93 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -154,6 +154,10 @@
'test/paths.h',
'test/pixel_test.cc',
'test/pixel_test.h',
+ 'test/pixel_test_output_surface.cc',
+ 'test/pixel_test_output_surface.h',
+ 'test/pixel_test_software_output_device.cc',
+ 'test/pixel_test_software_output_device.h',
'test/render_pass_test_common.cc',
'test/render_pass_test_common.h',
'test/render_pass_test_utils.cc',
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 5ec0621..e1354b9 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -13,6 +13,7 @@
#include "cc/base/thread.h"
#include "cc/layers/layer_impl.h"
#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
#include "third_party/WebKit/public/platform/WebAnimationDelegate.h"
@@ -652,17 +653,16 @@ void Layer::SetPositionConstraint(const LayerPositionConstraint& constraint) {
}
static void RunCopyCallbackOnMainThread(scoped_ptr<CopyOutputRequest> request,
- scoped_ptr<SkBitmap> bitmap) {
- if (request->HasBitmapRequest())
- request->SendBitmapResult(bitmap.Pass());
+ scoped_ptr<CopyOutputResult> result) {
+ request->SendResult(result.Pass());
}
static void PostCopyCallbackToMainThread(Thread* main_thread,
scoped_ptr<CopyOutputRequest> request,
- scoped_ptr<SkBitmap> bitmap) {
+ scoped_ptr<CopyOutputResult> result) {
main_thread->PostTask(base::Bind(&RunCopyCallbackOnMainThread,
base::Passed(&request),
- base::Passed(&bitmap)));
+ base::Passed(&result)));
}
void Layer::PushPropertiesTo(LayerImpl* layer) {
@@ -713,11 +713,13 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
it != copy_requests_.end();
++it) {
scoped_ptr<CopyOutputRequest> original_request = copy_requests_.take(it);
+ const CopyOutputRequest& original_request_ref = *original_request;
scoped_ptr<CopyOutputRequest> main_thread_request =
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &PostCopyCallbackToMainThread,
- layer_tree_host()->proxy()->MainThread(),
- base::Passed(&original_request)));
+ CopyOutputRequest::CreateRelayRequest(
+ original_request_ref,
+ base::Bind(&PostCopyCallbackToMainThread,
+ layer_tree_host()->proxy()->MainThread(),
+ base::Passed(&original_request)));
main_thread_copy_requests.push_back(main_thread_request.Pass());
}
copy_requests_.clear();
diff --git a/cc/output/copy_output_request.cc b/cc/output/copy_output_request.cc
index 437cce5..90ece04 100644
--- a/cc/output/copy_output_request.cc
+++ b/cc/output/copy_output_request.cc
@@ -4,27 +4,42 @@
#include "cc/output/copy_output_request.h"
+#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
+#include "cc/output/copy_output_result.h"
+#include "cc/resources/texture_mailbox.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace cc {
-CopyOutputRequest::CopyOutputRequest(const CopyAsBitmapCallback& callback)
- : bitmap_callback_(callback) {}
+CopyOutputRequest::CopyOutputRequest() {}
+
+CopyOutputRequest::CopyOutputRequest(
+ bool force_bitmap_result,
+ const CopyOutputRequestCallback& result_callback)
+ : force_bitmap_result_(force_bitmap_result),
+ result_callback_(result_callback) {
+}
CopyOutputRequest::~CopyOutputRequest() {
- SendEmptyResult();
+ if (!result_callback_.is_null())
+ SendResult(CopyOutputResult::CreateEmptyResult().Pass());
}
-void CopyOutputRequest::SendEmptyResult() {
- if (!bitmap_callback_.is_null())
- base::ResetAndReturn(&bitmap_callback_).Run(scoped_ptr<SkBitmap>());
+void CopyOutputRequest::SendResult(scoped_ptr<CopyOutputResult> result) {
+ base::ResetAndReturn(&result_callback_).Run(result.Pass());
}
void CopyOutputRequest::SendBitmapResult(scoped_ptr<SkBitmap> bitmap) {
- DCHECK(HasBitmapRequest());
- base::ResetAndReturn(&bitmap_callback_).Run(bitmap.Pass());
+ SendResult(CopyOutputResult::CreateBitmapResult(bitmap.Pass()).Pass());
+}
+
+void CopyOutputRequest::SendTextureResult(gfx::Size size,
+ scoped_ptr<TextureMailbox> texture) {
+ DCHECK(texture->IsTexture());
+ SendResult(CopyOutputResult::CreateTextureResult(size,
+ texture.Pass()).Pass());
}
} // namespace cc
diff --git a/cc/output/copy_output_request.h b/cc/output/copy_output_request.h
index d0ef48b..54fff1a 100644
--- a/cc/output/copy_output_request.h
+++ b/cc/output/copy_output_request.h
@@ -8,36 +8,59 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
+#include "ui/gfx/size.h"
class SkBitmap;
namespace cc {
+class CopyOutputResult;
+class TextureMailbox;
class CC_EXPORT CopyOutputRequest {
public:
- typedef base::Callback<void(scoped_ptr<SkBitmap>)> CopyAsBitmapCallback;
+ typedef base::Callback<void(scoped_ptr<CopyOutputResult> result)>
+ CopyOutputRequestCallback;
+ static scoped_ptr<CopyOutputRequest> CreateEmptyRequest() {
+ return make_scoped_ptr(new CopyOutputRequest);
+ }
+ static scoped_ptr<CopyOutputRequest> CreateRequest(
+ const CopyOutputRequestCallback& result_callback) {
+ return make_scoped_ptr(new CopyOutputRequest(false, result_callback));
+ }
static scoped_ptr<CopyOutputRequest> CreateBitmapRequest(
- const CopyAsBitmapCallback& bitmap_callback) {
- return make_scoped_ptr(new CopyOutputRequest(bitmap_callback));
+ const CopyOutputRequestCallback& result_callback) {
+ return make_scoped_ptr(new CopyOutputRequest(true, result_callback));
+ }
+ static scoped_ptr<CopyOutputRequest> CreateRelayRequest(
+ const CopyOutputRequest& original_request,
+ const CopyOutputRequestCallback& result_callback) {
+ return make_scoped_ptr(new CopyOutputRequest(
+ original_request.force_bitmap_result(), result_callback));
}
~CopyOutputRequest();
- bool IsEmpty() const { return !HasBitmapRequest(); }
- bool HasBitmapRequest() const { return !bitmap_callback_.is_null(); }
+ bool IsEmpty() const { return result_callback_.is_null(); }
+ bool force_bitmap_result() const { return force_bitmap_result_; }
- void SendEmptyResult();
+ void SendResult(scoped_ptr<CopyOutputResult> result);
void SendBitmapResult(scoped_ptr<SkBitmap> bitmap);
+ void SendTextureResult(gfx::Size size,
+ scoped_ptr<TextureMailbox> texture_mailbox);
bool Equals(const CopyOutputRequest& other) const {
- return bitmap_callback_.Equals(other.bitmap_callback_);
+ return result_callback_.Equals(other.result_callback_) &&
+ force_bitmap_result_ == other.force_bitmap_result_;
}
private:
- explicit CopyOutputRequest(const CopyAsBitmapCallback& callback);
+ CopyOutputRequest();
+ explicit CopyOutputRequest(bool force_bitmap_result,
+ const CopyOutputRequestCallback& result_callback);
- CopyAsBitmapCallback bitmap_callback_;
+ bool force_bitmap_result_;
+ CopyOutputRequestCallback result_callback_;
};
} // namespace cc
diff --git a/cc/output/copy_output_result.cc b/cc/output/copy_output_result.cc
new file mode 100644
index 0000000..412a55d
--- /dev/null
+++ b/cc/output/copy_output_result.cc
@@ -0,0 +1,39 @@
+// 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_result.h"
+
+#include "base/logging.h"
+#include "cc/resources/texture_mailbox.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace cc {
+
+CopyOutputResult::CopyOutputResult() {}
+
+CopyOutputResult::CopyOutputResult(scoped_ptr<SkBitmap> bitmap)
+ : size_(bitmap->width(), bitmap->height()),
+ bitmap_(bitmap.Pass()) {
+ DCHECK(bitmap_);
+}
+
+CopyOutputResult::CopyOutputResult(gfx::Size size,
+ scoped_ptr<TextureMailbox> texture_mailbox)
+ : size_(size),
+ texture_mailbox_(texture_mailbox.Pass()) {
+ DCHECK(texture_mailbox_);
+ DCHECK(texture_mailbox_->IsTexture());
+}
+
+CopyOutputResult::~CopyOutputResult() {}
+
+scoped_ptr<SkBitmap> CopyOutputResult::TakeBitmap() {
+ return bitmap_.Pass();
+}
+
+scoped_ptr<TextureMailbox> CopyOutputResult::TakeTexture() {
+ return texture_mailbox_.Pass();
+}
+
+} // namespace cc
diff --git a/cc/output/copy_output_result.h b/cc/output/copy_output_result.h
new file mode 100644
index 0000000..04cf2c6
--- /dev/null
+++ b/cc/output/copy_output_result.h
@@ -0,0 +1,55 @@
+// 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_RESULT_H_
+#define CC_OUTPUT_COPY_OUTPUT_RESULT_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+#include "ui/gfx/size.h"
+
+class SkBitmap;
+
+namespace cc {
+class TextureMailbox;
+
+class CC_EXPORT CopyOutputResult {
+ public:
+ static scoped_ptr<CopyOutputResult> CreateEmptyResult() {
+ return make_scoped_ptr(new CopyOutputResult);
+ }
+ static scoped_ptr<CopyOutputResult> CreateBitmapResult(
+ scoped_ptr<SkBitmap> bitmap) {
+ return make_scoped_ptr(new CopyOutputResult(bitmap.Pass()));
+ }
+ static scoped_ptr<CopyOutputResult> CreateTextureResult(
+ gfx::Size size,
+ scoped_ptr<TextureMailbox> texture_mailbox) {
+ return make_scoped_ptr(new CopyOutputResult(size, texture_mailbox.Pass()));
+ }
+
+ ~CopyOutputResult();
+
+ bool IsEmpty() const { return !HasBitmap() && !HasTexture(); }
+ bool HasBitmap() const { return !!bitmap_; }
+ bool HasTexture() const { return !!texture_mailbox_; }
+
+ gfx::Size size() const { return size_; }
+ scoped_ptr<SkBitmap> TakeBitmap();
+ scoped_ptr<TextureMailbox> TakeTexture();
+
+ private:
+ CopyOutputResult();
+ explicit CopyOutputResult(scoped_ptr<SkBitmap> bitmap);
+ explicit CopyOutputResult(gfx::Size size,
+ scoped_ptr<TextureMailbox> texture_mailbox);
+
+ gfx::Size size_;
+ scoped_ptr<SkBitmap> bitmap_;
+ scoped_ptr<TextureMailbox> texture_mailbox_;
+};
+
+} // namespace cc
+
+#endif // CC_OUTPUT_COPY_OUTPUT_RESULT_H_
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index fb5de4e..2a27ff7 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -21,6 +21,7 @@
#include "cc/output/compositor_frame_metadata.h"
#include "cc/output/context_provider.h"
#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
#include "cc/output/geometry_binding.h"
#include "cc/output/gl_frame_data.h"
#include "cc/output/output_surface.h"
@@ -136,7 +137,8 @@ GLRenderer::GLRenderer(RendererClient* client,
is_scissor_enabled_(false),
highp_threshold_min_(highp_threshold_min),
highp_threshold_cache_(0),
- on_demand_tile_raster_resource_id_(0) {
+ on_demand_tile_raster_resource_id_(0),
+ weak_factory_(this) {
DCHECK(context_);
}
@@ -599,19 +601,29 @@ scoped_ptr<ScopedResource> GLRenderer::DrawBackgroundFilters(
// FIXME: Do a single readback for both the surface and replica and cache the
// filtered results (once filter textures are not reused).
- gfx::Rect device_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect(
+ gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect(
contents_device_transform, SharedGeometryQuad().BoundingBox()));
int top, right, bottom, left;
filters.getOutsets(top, right, bottom, left);
- device_rect.Inset(-left, -top, -right, -bottom);
+ window_rect.Inset(-left, -top, -right, -bottom);
- device_rect.Intersect(frame->current_render_pass->output_rect);
+ window_rect.Intersect(
+ MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect));
scoped_ptr<ScopedResource> device_background_texture =
ScopedResource::create(resource_provider_);
- if (!GetFramebufferTexture(device_background_texture.get(), device_rect))
+ if (!device_background_texture->Allocate(window_rect.size(),
+ GL_RGB,
+ ResourceProvider::TextureUsageAny)) {
return scoped_ptr<ScopedResource>();
+ } else {
+ ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
+ device_background_texture->id());
+ GetFramebufferTexture(lock.texture_id(),
+ device_background_texture->format(),
+ window_rect);
+ }
SkBitmap filtered_device_background =
ApplyFilters(this, filters, device_background_texture.get());
@@ -658,7 +670,7 @@ scoped_ptr<ScopedResource> GLRenderer::DrawBackgroundFilters(
CopyTextureToFramebuffer(frame,
filtered_device_background_texture_id,
- device_rect,
+ window_rect,
device_to_framebuffer_transform,
flip_vertically);
}
@@ -2135,11 +2147,20 @@ void GLRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) {
pending_read.Pass());
// This is a syncronous call since the callback is null.
+ gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect);
DoGetFramebufferPixels(static_cast<uint8*>(pixels),
- rect,
+ window_rect,
AsyncGetFramebufferPixelsCleanupCallback());
}
+void GLRenderer::DeleteTextureReleaseCallback(unsigned texture_id,
+ unsigned sync_point,
+ bool lost_resource) {
+ if (sync_point)
+ context_->waitSyncPoint(sync_point);
+ context_->deleteTexture(texture_id);
+}
+
void GLRenderer::GetFramebufferPixelsAsync(
gfx::Rect rect, scoped_ptr<CopyOutputRequest> request) {
DCHECK(!request->IsEmpty());
@@ -2148,8 +2169,56 @@ void GLRenderer::GetFramebufferPixelsAsync(
if (rect.IsEmpty())
return;
+ DCHECK(gfx::Rect(current_surface_size_).Contains(rect)) <<
+ "current_surface_size_: " << current_surface_size_.ToString() <<
+ " rect: " << rect.ToString();
+
+ gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect);
+
+ if (!request->force_bitmap_result()) {
+ unsigned int texture_id = context_->createTexture();
+ GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+ GetFramebufferTexture(texture_id, GL_RGBA, window_rect);
+
+ gpu::Mailbox mailbox;
+ unsigned sync_point = 0;
+ GLC(context_, context_->genMailboxCHROMIUM(mailbox.name));
+ if (mailbox.IsZero()) {
+ context_->deleteTexture(texture_id);
+ request->SendResult(CopyOutputResult::CreateEmptyResult());
+ return;
+ }
+
+ GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id));
+ GLC(context_, context_->produceTextureCHROMIUM(
+ GL_TEXTURE_2D, mailbox.name));
+ GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0));
+ sync_point = context_->insertSyncPoint();
+ scoped_ptr<TextureMailbox> texture_mailbox = make_scoped_ptr(
+ new TextureMailbox(mailbox,
+ base::Bind(&GLRenderer::DeleteTextureReleaseCallback,
+ weak_factory_.GetWeakPtr(),
+ texture_id),
+ GL_TEXTURE_2D,
+ sync_point));
+ request->SendTextureResult(window_rect.size(), texture_mailbox.Pass());
+ return;
+ }
+
+ DCHECK(request->force_bitmap_result());
+
scoped_ptr<SkBitmap> bitmap(new SkBitmap);
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config,
+ window_rect.width(),
+ window_rect.height());
bitmap->allocPixels();
scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
@@ -2169,14 +2238,15 @@ void GLRenderer::GetFramebufferPixelsAsync(
pending_read.Pass());
// This is an asyncronous call since the callback is not null.
- DoGetFramebufferPixels(pixels, rect, cleanup_callback);
+ DoGetFramebufferPixels(pixels, window_rect, cleanup_callback);
}
void GLRenderer::DoGetFramebufferPixels(
uint8* dest_pixels,
- gfx::Rect rect,
+ gfx::Rect window_rect,
const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) {
- gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect);
+ DCHECK_GE(window_rect.x(), 0);
+ DCHECK_GE(window_rect.y(), 0);
DCHECK_LE(window_rect.right(), current_surface_size_.width());
DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
@@ -2198,48 +2268,37 @@ void GLRenderer::DoGetFramebufferPixels(
temporary_texture = context_->createTexture();
GLC(context_, context_->bindTexture(GL_TEXTURE_2D, temporary_texture));
- GLC(context_,
- context_->texParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- GLC(context_,
- context_->texParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- GLC(context_,
- context_->texParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- GLC(context_,
- context_->texParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GLC(context_, context_->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
// Copy the contents of the current (IOSurface-backed) framebuffer into a
// temporary texture.
- GLC(context_,
- context_->copyTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- 0,
- 0,
- current_surface_size_.width(),
- current_surface_size_.height(),
- 0));
+ GetFramebufferTexture(temporary_texture,
+ GL_RGBA,
+ gfx::Rect(current_surface_size_));
temporary_fbo = context_->createFramebuffer();
// Attach this texture to an FBO, and perform the readback from that FBO.
GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, temporary_fbo));
- GLC(context_,
- context_->framebufferTexture2D(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D,
- temporary_texture,
- 0));
+ GLC(context_, context_->framebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ temporary_texture,
+ 0));
- DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) ==
- GL_FRAMEBUFFER_COMPLETE);
+ DCHECK_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE),
+ context_->checkFramebufferStatus(GL_FRAMEBUFFER));
}
unsigned buffer = context_->createBuffer();
GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
buffer));
GLC(context_, context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
- 4 * rect.size().GetArea(),
+ 4 * window_rect.size().GetArea(),
NULL,
GL_STREAM_READ));
@@ -2269,7 +2328,7 @@ void GLRenderer::DoGetFramebufferPixels(
cleanup_callback,
buffer,
dest_pixels,
- rect.size());
+ window_rect.size());
// Save the finished_callback so it can be cancelled.
pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset(
finished_callback);
@@ -2348,35 +2407,33 @@ void GLRenderer::PassOnSkBitmap(
scoped_ptr<SkAutoLockPixels> lock,
scoped_ptr<CopyOutputRequest> request,
bool success) {
- DCHECK(request->HasBitmapRequest());
+ DCHECK(request->force_bitmap_result());
lock.reset();
if (success)
request->SendBitmapResult(bitmap.Pass());
}
-bool GLRenderer::GetFramebufferTexture(ScopedResource* texture,
- gfx::Rect device_rect) {
- DCHECK(!texture->id() || (texture->size() == device_rect.size() &&
- texture->format() == GL_RGB));
-
- if (!texture->id() && !texture->Allocate(device_rect.size(),
- GL_RGB,
- ResourceProvider::TextureUsageAny))
- return false;
+void GLRenderer::GetFramebufferTexture(unsigned texture_id,
+ unsigned texture_format,
+ gfx::Rect window_rect) {
+ DCHECK(texture_id);
+ DCHECK_GE(window_rect.x(), 0);
+ DCHECK_GE(window_rect.y(), 0);
+ DCHECK_LE(window_rect.right(), current_surface_size_.width());
+ DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
- ResourceProvider::ScopedWriteLockGL lock(resource_provider_, texture->id());
- GLC(context_, context_->bindTexture(GL_TEXTURE_2D, lock.texture_id()));
+ GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id));
GLC(context_,
context_->copyTexImage2D(GL_TEXTURE_2D,
0,
- texture->format(),
- device_rect.x(),
- device_rect.y(),
- device_rect.width(),
- device_rect.height(),
+ texture_format,
+ window_rect.x(),
+ window_rect.y(),
+ window_rect.width(),
+ window_rect.height(),
0));
- return true;
+ GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0));
}
bool GLRenderer::UseScopedTexture(DrawingFrame* frame,
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index e5d80f1..21acdde 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -96,7 +96,9 @@ class CC_EXPORT GLRenderer
void GetFramebufferPixelsAsync(gfx::Rect rect,
scoped_ptr<CopyOutputRequest> request);
- bool GetFramebufferTexture(ScopedResource* resource, gfx::Rect device_rect);
+ void GetFramebufferTexture(unsigned texture_id,
+ unsigned texture_format,
+ gfx::Rect device_rect);
void ReleaseRenderPassTextures();
virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) OVERRIDE;
@@ -197,18 +199,20 @@ class CC_EXPORT GLRenderer
AsyncGetFramebufferPixelsCleanupCallback;
void DoGetFramebufferPixels(
uint8* pixels,
- gfx::Rect rect,
+ gfx::Rect window_rect,
const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback);
void FinishedReadback(
const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback,
unsigned source_buffer,
uint8_t* dest_pixels,
gfx::Size size);
- void PassOnSkBitmap(
- scoped_ptr<SkBitmap> bitmap,
- scoped_ptr<SkAutoLockPixels> lock,
- scoped_ptr<CopyOutputRequest> request,
- bool success);
+ void PassOnSkBitmap(scoped_ptr<SkBitmap> bitmap,
+ scoped_ptr<SkAutoLockPixels> lock,
+ scoped_ptr<CopyOutputRequest> request,
+ bool success);
+ void DeleteTextureReleaseCallback(unsigned texture_id,
+ unsigned sync_point,
+ bool lost_resource);
void ReinitializeGrCanvas();
void ReinitializeGLState();
@@ -431,6 +435,8 @@ class CC_EXPORT GLRenderer
SkBitmap on_demand_tile_raster_bitmap_;
ResourceProvider::ResourceId on_demand_tile_raster_resource_id_;
+ base::WeakPtrFactory<GLRenderer> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(GLRenderer);
};
diff --git a/cc/quads/render_pass_unittest.cc b/cc/quads/render_pass_unittest.cc
index 1ab41e8..fdeb4f0 100644
--- a/cc/quads/render_pass_unittest.cc
+++ b/cc/quads/render_pass_unittest.cc
@@ -50,8 +50,7 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) {
transform_to_root,
has_transparent_background,
has_occlusion_from_outside_target_surface);
- pass->copy_requests.push_back(CopyOutputRequest::CreateBitmapRequest(
- CopyOutputRequest::CopyAsBitmapCallback()));
+ pass->copy_requests.push_back(CopyOutputRequest::CreateEmptyRequest());
// Stick a quad in the pass, this should not get copied.
scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 3c67e54..3d757ca 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -6,8 +6,12 @@
#include "base/path_service.h"
#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
+#include "cc/resources/texture_mailbox.h"
#include "cc/test/paths.h"
#include "cc/test/pixel_comparator.h"
+#include "cc/test/pixel_test_output_surface.h"
+#include "cc/test/pixel_test_software_output_device.h"
#include "cc/test/pixel_test_utils.h"
#include "cc/trees/layer_tree_impl.h"
#include "ui/gl/gl_implementation.h"
@@ -17,19 +21,37 @@
namespace cc {
LayerTreePixelTest::LayerTreePixelTest()
- : pixel_comparator_(new ExactPixelComparator(true)) {}
+ : pixel_comparator_(new ExactPixelComparator(true)), use_gl_(true) {}
LayerTreePixelTest::~LayerTreePixelTest() {}
scoped_ptr<OutputSurface> LayerTreePixelTest::CreateOutputSurface() {
- CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL));
-
- using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
- scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d(
- WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
- WebKit::WebGraphicsContext3D::Attributes()));
- return make_scoped_ptr(
- new OutputSurface(context3d.PassAs<WebKit::WebGraphicsContext3D>()));
+ gfx::Vector2d viewport_offset(20, 10);
+ gfx::Size surface_expansion_size(40, 60);
+ scoped_ptr<PixelTestOutputSurface> output_surface;
+
+ if (!use_gl_) {
+ scoped_ptr<PixelTestSoftwareOutputDevice> software_output_device(
+ new PixelTestSoftwareOutputDevice);
+ software_output_device->set_surface_expansion_size(surface_expansion_size);
+ output_surface = make_scoped_ptr(
+ new PixelTestOutputSurface(
+ software_output_device.PassAs<SoftwareOutputDevice>()));
+ } else {
+ CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL));
+
+ using WebKit::WebGraphicsContext3D;
+ using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
+ scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d(
+ WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
+ WebGraphicsContext3D::Attributes()));
+ output_surface = make_scoped_ptr(
+ new PixelTestOutputSurface(context3d.PassAs<WebGraphicsContext3D>()));
+ }
+
+ output_surface->set_viewport_offset(viewport_offset);
+ output_surface->set_surface_expansion_size(surface_expansion_size);
+ return output_surface.PassAs<OutputSurface>();
}
scoped_refptr<cc::ContextProvider>
@@ -48,31 +70,36 @@ LayerTreePixelTest::OffscreenContextProviderForCompositorThread() {
return provider;
}
-void LayerTreePixelTest::ReadbackResult(scoped_ptr<SkBitmap> bitmap) {
- ASSERT_TRUE(bitmap);
-
- base::FilePath test_data_dir;
- EXPECT_TRUE(PathService::Get(cc::DIR_TEST_DATA, &test_data_dir));
-
- // To rebaseline:
- // EXPECT_TRUE(WritePNGFile(*bitmap, test_data_dir.Append(ref_file_), true));
+scoped_ptr<CopyOutputRequest> LayerTreePixelTest::CreateCopyOutputRequest() {
+ return CopyOutputRequest::CreateBitmapRequest(
+ base::Bind(&LayerTreePixelTest::ReadbackResult, base::Unretained(this)));
+}
- EXPECT_TRUE(MatchesPNGFile(*bitmap,
- test_data_dir.Append(ref_file_),
- *pixel_comparator_));
+void LayerTreePixelTest::ReadbackResult(scoped_ptr<CopyOutputResult> result) {
+ ASSERT_TRUE(result->HasBitmap());
+ result_bitmap_ = result->TakeBitmap().Pass();
EndTest();
}
void LayerTreePixelTest::BeginTest() {
Layer* target = readback_target_ ? readback_target_
: layer_tree_host()->root_layer();
- target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreePixelTest::ReadbackResult,
- base::Unretained(this))));
+ target->RequestCopyOfOutput(CreateCopyOutputRequest().Pass());
PostSetNeedsCommitToMainThread();
}
-void LayerTreePixelTest::AfterTest() {}
+void LayerTreePixelTest::AfterTest() {
+ base::FilePath test_data_dir;
+ EXPECT_TRUE(PathService::Get(cc::DIR_TEST_DATA, &test_data_dir));
+ base::FilePath ref_file_path = test_data_dir.Append(ref_file_);
+
+ // To rebaseline:
+ // EXPECT_TRUE(WritePNGFile(*result_bitmap_, ref_file_path, true));
+
+ EXPECT_TRUE(MatchesPNGFile(*result_bitmap_,
+ ref_file_path,
+ *pixel_comparator_));
+}
scoped_refptr<SolidColorLayer> LayerTreePixelTest::CreateSolidColorLayer(
gfx::Rect rect, SkColor color) {
@@ -140,4 +167,81 @@ void LayerTreePixelTest::SetupTree() {
LayerTreeTest::SetupTree();
}
+scoped_ptr<SkBitmap> LayerTreePixelTest::CopyTextureMailboxToBitmap(
+ gfx::Size size,
+ const TextureMailbox& texture_mailbox) {
+ DCHECK(texture_mailbox.IsTexture());
+ if (!texture_mailbox.IsTexture())
+ return scoped_ptr<SkBitmap>();
+
+ using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
+ scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d(
+ WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
+ WebKit::WebGraphicsContext3D::Attributes()));
+
+ EXPECT_TRUE(context3d->makeContextCurrent());
+
+ if (texture_mailbox.sync_point())
+ context3d->waitSyncPoint(texture_mailbox.sync_point());
+
+ unsigned texture_id = context3d->createTexture();
+ context3d->bindTexture(GL_TEXTURE_2D, texture_id);
+ context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ context3d->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ context3d->texParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ context3d->consumeTextureCHROMIUM(texture_mailbox.target(),
+ texture_mailbox.data());
+ context3d->bindTexture(GL_TEXTURE_2D, 0);
+
+ unsigned fbo = context3d->createFramebuffer();
+ context3d->bindFramebuffer(GL_FRAMEBUFFER, fbo);
+ context3d->framebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ texture_id,
+ 0);
+ EXPECT_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE),
+ context3d->checkFramebufferStatus(GL_FRAMEBUFFER));
+
+ scoped_ptr<uint8[]> pixels(new uint8[size.GetArea() * 4]);
+ context3d->readPixels(0,
+ 0,
+ size.width(),
+ size.height(),
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ pixels.get());
+
+ context3d->deleteFramebuffer(fbo);
+ context3d->deleteTexture(texture_id);
+
+ scoped_ptr<SkBitmap> bitmap(new SkBitmap);
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config,
+ size.width(),
+ size.height());
+ bitmap->allocPixels();
+
+ scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
+ uint8* out_pixels = static_cast<uint8*>(bitmap->getPixels());
+
+ size_t row_bytes = size.width() * 4;
+ size_t total_bytes = size.height() * row_bytes;
+ for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) {
+ // Flip Y axis.
+ size_t src_y = total_bytes - dest_y - row_bytes;
+ // Swizzle OpenGL -> Skia byte order.
+ for (size_t x = 0; x < row_bytes; x += 4) {
+ out_pixels[dest_y + x + SK_R32_SHIFT/8] = pixels.get()[src_y + x + 0];
+ out_pixels[dest_y + x + SK_G32_SHIFT/8] = pixels.get()[src_y + x + 1];
+ out_pixels[dest_y + x + SK_B32_SHIFT/8] = pixels.get()[src_y + x + 2];
+ out_pixels[dest_y + x + SK_A32_SHIFT/8] = pixels.get()[src_y + x + 3];
+ }
+ }
+
+ return bitmap.Pass();
+}
+
} // namespace cc
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h
index 1e5ddae..b485237 100644
--- a/cc/test/layer_tree_pixel_test.h
+++ b/cc/test/layer_tree_pixel_test.h
@@ -11,9 +11,14 @@
#ifndef CC_TEST_LAYER_TREE_PIXEL_TEST_H_
#define CC_TEST_LAYER_TREE_PIXEL_TEST_H_
+class SkBitmap;
+
namespace cc {
+class CopyOutputRequest;
+class CopyOutputResult;
class LayerTreeHost;
class PixelComparator;
+class TextureMailbox;
class LayerTreePixelTest : public LayerTreeTest {
protected:
@@ -26,7 +31,9 @@ class LayerTreePixelTest : public LayerTreeTest {
virtual scoped_refptr<cc::ContextProvider>
OffscreenContextProviderForCompositorThread() OVERRIDE;
- void ReadbackResult(scoped_ptr<SkBitmap> bitmap);
+ virtual scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest();
+
+ void ReadbackResult(scoped_ptr<CopyOutputResult> result);
virtual void BeginTest() OVERRIDE;
virtual void SetupTree() OVERRIDE;
@@ -47,6 +54,10 @@ class LayerTreePixelTest : public LayerTreeTest {
Layer* target,
base::FilePath file_name);
+ scoped_ptr<SkBitmap> CopyTextureMailboxToBitmap(
+ gfx::Size size,
+ const TextureMailbox& texture_mailbox);
+
// Common CSS colors defined for tests to use.
enum Colors {
kCSSOrange = 0xffffa500,
@@ -56,10 +67,12 @@ class LayerTreePixelTest : public LayerTreeTest {
scoped_ptr<PixelComparator> pixel_comparator_;
- private:
+ protected:
+ bool use_gl_;
scoped_refptr<Layer> content_root_;
Layer* readback_target_;
base::FilePath ref_file_;
+ scoped_ptr<SkBitmap> result_bitmap_;
};
} // namespace cc
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 1e75156..654804b 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -8,11 +8,14 @@
#include "base/run_loop.h"
#include "cc/output/compositor_frame_metadata.h"
#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
#include "cc/output/gl_renderer.h"
-#include "cc/output/output_surface.h"
+#include "cc/output/output_surface_client.h"
#include "cc/output/software_renderer.h"
#include "cc/resources/resource_provider.h"
#include "cc/test/paths.h"
+#include "cc/test/pixel_test_output_surface.h"
+#include "cc/test/pixel_test_software_output_device.h"
#include "cc/test/pixel_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_implementation.h"
@@ -21,14 +24,15 @@
namespace cc {
-class PixelTest::PixelTestRendererClient : public RendererClient {
+class PixelTest::PixelTestRendererClient
+ : public RendererClient, public OutputSurfaceClient {
public:
explicit PixelTestRendererClient(gfx::Rect device_viewport)
: device_viewport_(device_viewport) {}
// RendererClient implementation.
virtual gfx::Rect DeviceViewport() const OVERRIDE {
- return device_viewport_ + test_expansion_offset_;
+ return device_viewport_;
}
virtual float DeviceScaleFactor() const OVERRIDE {
return 1.f;
@@ -51,56 +55,25 @@ class PixelTest::PixelTestRendererClient : public RendererClient {
return true;
}
- void SetTestExpansionOffset(gfx::Vector2d test_expansion_offset) {
- test_expansion_offset_ = test_expansion_offset;
+ // OutputSurfaceClient implementation.
+ virtual bool DeferredInitialize(
+ scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE {
+ return false;
+ }
+ virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {}
+ virtual void BeginFrame(base::TimeTicks frame_time) OVERRIDE {}
+ virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {}
+ virtual void DidLoseOutputSurface() OVERRIDE {}
+ virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
+ gfx::Rect viewport) OVERRIDE {
+ device_viewport_ = viewport;
}
private:
gfx::Rect device_viewport_;
- gfx::Vector2d test_expansion_offset_;
LayerTreeSettings settings_;
};
-class PixelTest::PixelTestOutputSurface : public OutputSurface {
- public:
- explicit PixelTestOutputSurface(
- scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
- : OutputSurface(context3d.Pass()) {}
- explicit PixelTestOutputSurface(
- scoped_ptr<cc::SoftwareOutputDevice> software_device)
- : OutputSurface(software_device.Pass()) {}
- virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE {
- OutputSurface::Reshape(
- gfx::Size(size.width() + test_expansion_size_.width(),
- size.height() + test_expansion_size_.height()),
- scale_factor);
- }
-
- void SetTestExpansionSize(gfx::Size test_expansion_size) {
- test_expansion_size_ = test_expansion_size;
- }
-
- private:
- gfx::Size test_expansion_size_;
-};
-
-class PixelTestSoftwareOutputDevice : public SoftwareOutputDevice {
- public:
- PixelTestSoftwareOutputDevice() {}
- virtual void Resize(gfx::Size size) OVERRIDE {
- SoftwareOutputDevice::Resize(
- gfx::Size(size.width() + test_expansion_size_.width(),
- size.height() + test_expansion_size_.height()));
- }
-
- void SetTestExpansionSize(gfx::Size test_expansion_size) {
- test_expansion_size_ = test_expansion_size;
- }
-
- private:
- gfx::Size test_expansion_size_;
-};
-
PixelTest::PixelTest()
: device_viewport_size_(gfx::Size(200, 200)),
fake_client_(
@@ -140,8 +113,9 @@ bool PixelTest::RunPixelTestWithReadbackTarget(
}
void PixelTest::ReadbackResult(base::Closure quit_run_loop,
- scoped_ptr<SkBitmap> bitmap) {
- result_bitmap_ = bitmap.Pass();
+ scoped_ptr<CopyOutputResult> result) {
+ ASSERT_TRUE(result->HasBitmap());
+ result_bitmap_ = result->TakeBitmap().Pass();
quit_run_loop.Run();
}
@@ -173,6 +147,8 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) {
WebKit::WebGraphicsContext3D::Attributes()));
output_surface_.reset(new PixelTestOutputSurface(
context3d.PassAs<WebKit::WebGraphicsContext3D>()));
+ output_surface_->BindToClient(fake_client_.get());
+
resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
renderer_ = GLRenderer::Create(fake_client_.get(),
output_surface_.get(),
@@ -189,12 +165,13 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) {
void PixelTest::ForceExpandedViewport(gfx::Size surface_expansion,
gfx::Vector2d viewport_offset) {
static_cast<PixelTestOutputSurface*>(output_surface_.get())
- ->SetTestExpansionSize(surface_expansion);
- fake_client_->SetTestExpansionOffset(viewport_offset);
+ ->set_surface_expansion_size(surface_expansion);
+ static_cast<PixelTestOutputSurface*>(output_surface_.get())
+ ->set_viewport_offset(viewport_offset);
SoftwareOutputDevice* device = output_surface_->software_device();
if (device) {
static_cast<PixelTestSoftwareOutputDevice*>(device)
- ->SetTestExpansionSize(surface_expansion);
+ ->set_surface_expansion_size(surface_expansion);
}
}
@@ -203,6 +180,7 @@ void PixelTest::SetUpSoftwareRenderer() {
scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice());
output_surface_.reset(new PixelTestOutputSurface(device.Pass()));
+ output_surface_->BindToClient(fake_client_.get());
resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
renderer_ = SoftwareRenderer::Create(
fake_client_.get(),
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
index eb53e07..3c607ae 100644
--- a/cc/test/pixel_test.h
+++ b/cc/test/pixel_test.h
@@ -14,6 +14,7 @@
#define CC_TEST_PIXEL_TEST_H_
namespace cc {
+class CopyOutputResult;
class DirectRenderer;
class SoftwareRenderer;
class OutputSurface;
@@ -34,7 +35,6 @@ class PixelTest : public testing::Test {
const PixelComparator& comparator);
gfx::Size device_viewport_size_;
- class PixelTestOutputSurface;
class PixelTestRendererClient;
scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<ResourceProvider> resource_provider_;
@@ -49,7 +49,8 @@ class PixelTest : public testing::Test {
gfx::Vector2d viewport_offset);
private:
- void ReadbackResult(base::Closure quit_run_loop, scoped_ptr<SkBitmap> bitmap);
+ void ReadbackResult(base::Closure quit_run_loop,
+ scoped_ptr<CopyOutputResult> result);
bool PixelsMatchReference(const base::FilePath& ref_file,
const PixelComparator& comparator);
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc
new file mode 100644
index 0000000..9a4d66a
--- /dev/null
+++ b/cc/test/pixel_test_output_surface.cc
@@ -0,0 +1,21 @@
+// 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/test/pixel_test_output_surface.h"
+
+#include "cc/output/output_surface_client.h"
+#include "ui/gfx/transform.h"
+
+namespace cc {
+
+void PixelTestOutputSurface::Reshape(gfx::Size size, float scale_factor) {
+ gfx::Size expanded_size(size.width() + surface_expansion_size_.width(),
+ size.height() + surface_expansion_size_.height());
+ OutputSurface::Reshape(expanded_size, scale_factor);
+
+ gfx::Rect offset_viewport = gfx::Rect(size) + viewport_offset_;
+ SetExternalDrawConstraints(gfx::Transform(), offset_viewport);
+}
+
+} // namespace cc
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h
new file mode 100644
index 0000000..ec7a828
--- /dev/null
+++ b/cc/test/pixel_test_output_surface.h
@@ -0,0 +1,37 @@
+// 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_TEST_PIXEL_TEST_OUTPUT_SURFACE_H_
+#define CC_TEST_PIXEL_TEST_OUTPUT_SURFACE_H_
+
+#include "cc/output/output_surface.h"
+
+namespace cc {
+
+class PixelTestOutputSurface : public OutputSurface {
+ public:
+ explicit PixelTestOutputSurface(
+ scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
+ : OutputSurface(context3d.Pass()) {}
+ explicit PixelTestOutputSurface(
+ scoped_ptr<cc::SoftwareOutputDevice> software_device)
+ : OutputSurface(software_device.Pass()) {}
+
+ virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE;
+
+ void set_surface_expansion_size(gfx::Size surface_expansion_size) {
+ surface_expansion_size_ = surface_expansion_size;
+ }
+ void set_viewport_offset(gfx::Vector2d viewport_offset) {
+ viewport_offset_ = viewport_offset;
+ }
+
+ private:
+ gfx::Size surface_expansion_size_;
+ gfx::Vector2d viewport_offset_;
+};
+
+} // namespace cc
+
+#endif // CC_TEST_PIXEL_TEST_OUTPUT_SURFACE_H_
diff --git a/cc/test/pixel_test_software_output_device.cc b/cc/test/pixel_test_software_output_device.cc
new file mode 100644
index 0000000..d4f0b88
--- /dev/null
+++ b/cc/test/pixel_test_software_output_device.cc
@@ -0,0 +1,15 @@
+// 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/test/pixel_test_software_output_device.h"
+
+namespace cc {
+
+void PixelTestSoftwareOutputDevice::Resize(gfx::Size size) {
+ gfx::Size expanded_size(size.width() + surface_expansion_size_.width(),
+ size.height() + surface_expansion_size_.height());
+ SoftwareOutputDevice::Resize(expanded_size);
+}
+
+} // namespace cc
diff --git a/cc/test/pixel_test_software_output_device.h b/cc/test/pixel_test_software_output_device.h
new file mode 100644
index 0000000..b652063
--- /dev/null
+++ b/cc/test/pixel_test_software_output_device.h
@@ -0,0 +1,26 @@
+// 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_TEST_PIXEL_TEST_SOFTWARE_OUTPUT_DEVICE_H_
+#define CC_TEST_PIXEL_TEST_SOFTWARE_OUTPUT_DEVICE_H_
+
+#include "cc/output/software_output_device.h"
+
+namespace cc {
+
+class PixelTestSoftwareOutputDevice : public SoftwareOutputDevice {
+ public:
+ virtual void Resize(gfx::Size size) OVERRIDE;
+
+ void set_surface_expansion_size(gfx::Size surface_expansion_size) {
+ surface_expansion_size_ = surface_expansion_size;
+ }
+
+ private:
+ gfx::Size surface_expansion_size_;
+};
+
+} // namespace cc
+
+#endif // CC_TEST_PIXEL_TEST_SOFTWARE_OUTPUT_DEVICE_H_
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc
index 5383bfd1..3c7e346 100644
--- a/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -60,7 +60,7 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
"background_filter_blur_outsets.png")));
}
-TEST_F(LayerTreeHostFiltersPixelTest, DISABLED_BackgroundFilterBlurOffAxis) {
+TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc
index f6a6ccb..cd59ed5 100644
--- a/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -3,16 +3,113 @@
// found in the LICENSE file.
#include "build/build_config.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
#include "cc/test/layer_tree_pixel_test.h"
+#include "cc/test/paths.h"
#if !defined(OS_ANDROID)
namespace cc {
namespace {
-class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest {};
+class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest {
+ protected:
+ LayerTreeHostReadbackPixelTest() : force_readback_as_bitmap_(false) {}
+
+ virtual scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest() OVERRIDE {
+ if (force_readback_as_bitmap_) {
+ return CopyOutputRequest::CreateBitmapRequest(
+ base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
+ base::Unretained(this)));
+ }
+
+ if (!use_gl_) {
+ return CopyOutputRequest::CreateRequest(
+ base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
+ base::Unretained(this)));
+ }
+
+ return CopyOutputRequest::CreateRequest(
+ base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture,
+ base::Unretained(this)));
+ }
+
+ void ReadbackResultAsBitmap(scoped_ptr<CopyOutputResult> result) {
+ EXPECT_TRUE(result->HasBitmap());
+ result_bitmap_ = result->TakeBitmap().Pass();
+ EndTest();
+ }
+
+ void ReadbackResultAsTexture(scoped_ptr<CopyOutputResult> result) {
+ EXPECT_TRUE(result->HasTexture());
+
+ scoped_ptr<TextureMailbox> texture_mailbox = result->TakeTexture().Pass();
+ EXPECT_TRUE(texture_mailbox->IsValid());
+ EXPECT_TRUE(texture_mailbox->IsTexture());
+
+ scoped_ptr<SkBitmap> bitmap =
+ CopyTextureMailboxToBitmap(result->size(), *texture_mailbox);
+ ReadbackResultAsBitmap(CopyOutputResult::CreateBitmapResult(bitmap.Pass()));
+
+ texture_mailbox->RunReleaseCallback(0, false);
+ }
+
+ bool force_readback_as_bitmap_;
+};
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software) {
+ use_gl_ = false;
+ force_readback_as_bitmap_ = false;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorGREEN);
+ background->AddChild(green);
+
+ RunPixelTest(background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "green.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software_Bitmap) {
+ use_gl_ = false;
+ force_readback_as_bitmap_ = true;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorGREEN);
+ background->AddChild(green);
+
+ RunPixelTest(background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "green.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL_Bitmap) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = true;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorGREEN);
+ background->AddChild(green);
+
+ RunPixelTest(background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "green.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = false;
-TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
@@ -25,7 +122,11 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer) {
"green.png")));
}
-TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild) {
+TEST_F(LayerTreeHostReadbackPixelTest,
+ ReadbackRootLayerWithChild_Software) {
+ use_gl_ = false;
+ force_readback_as_bitmap_ = false;
+
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
@@ -42,7 +143,50 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild) {
"green_with_blue_corner.png")));
}
-TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer) {
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL_Bitmap) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = true;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorGREEN);
+ background->AddChild(green);
+
+ scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
+ gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
+ green->AddChild(blue);
+
+ RunPixelTest(background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "green_with_blue_corner.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = false;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorGREEN);
+ background->AddChild(green);
+
+ scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
+ gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
+ green->AddChild(blue);
+
+ RunPixelTest(background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "green_with_blue_corner.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_Software) {
+ use_gl_ = false;
+ force_readback_as_bitmap_ = false;
+
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
@@ -56,7 +200,62 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer) {
"green.png")));
}
-TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer) {
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL_Bitmap) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = true;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorGREEN);
+ background->AddChild(green);
+
+ RunPixelTestWithReadbackTarget(background,
+ green.get(),
+ base::FilePath(FILE_PATH_LITERAL(
+ "green.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = false;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorGREEN);
+ background->AddChild(green);
+
+ RunPixelTestWithReadbackTarget(background,
+ green.get(),
+ base::FilePath(FILE_PATH_LITERAL(
+ "green.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest,
+ ReadbackSmallNonRootLayer_Software) {
+ use_gl_ = false;
+ force_readback_as_bitmap_ = false;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+ background->AddChild(green);
+
+ RunPixelTestWithReadbackTarget(background,
+ green.get(),
+ base::FilePath(FILE_PATH_LITERAL(
+ "green_small.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL_Bitmap) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = true;
+
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
@@ -70,7 +269,71 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer) {
"green_small.png")));
}
-TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild) {
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = false;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+ background->AddChild(green);
+
+ RunPixelTestWithReadbackTarget(background,
+ green.get(),
+ base::FilePath(FILE_PATH_LITERAL(
+ "green_small.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest,
+ ReadbackSmallNonRootLayerWithChild_Software) {
+ use_gl_ = false;
+ force_readback_as_bitmap_ = false;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+ background->AddChild(green);
+
+ scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
+ gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+ green->AddChild(blue);
+
+ RunPixelTestWithReadbackTarget(background,
+ green.get(),
+ base::FilePath(FILE_PATH_LITERAL(
+ "green_small_with_blue_corner.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest,
+ ReadbackSmallNonRootLayerWithChild_GL_Bitmap) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = true;
+
+ scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
+ gfx::Rect(200, 200), SK_ColorWHITE);
+
+ scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
+ gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+ background->AddChild(green);
+
+ scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
+ gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+ green->AddChild(blue);
+
+ RunPixelTestWithReadbackTarget(background,
+ green.get(),
+ base::FilePath(FILE_PATH_LITERAL(
+ "green_small_with_blue_corner.png")));
+}
+
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL) {
+ use_gl_ = true;
+ force_readback_as_bitmap_ = false;
+
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index e4d192e..f4d245b 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -16,6 +16,7 @@
#include "cc/layers/picture_layer.h"
#include "cc/layers/scrollbar_layer.h"
#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
#include "cc/output/output_surface.h"
#include "cc/resources/prioritized_resource.h"
#include "cc/resources/prioritized_resource_manager.h"
@@ -2526,7 +2527,7 @@ class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
switch (frame) {
case 1:
child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::BitmapCallback,
+ base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
base::Unretained(this))));
EXPECT_EQ(0u, callbacks_.size());
break;
@@ -2539,13 +2540,13 @@ class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::BitmapCallback,
+ base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
base::Unretained(this))));
root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::BitmapCallback,
+ base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
base::Unretained(this))));
child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::BitmapCallback,
+ base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
base::Unretained(this))));
EXPECT_EQ(1u, callbacks_.size());
break;
@@ -2565,10 +2566,13 @@ class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
}
}
- void BitmapCallback(scoped_ptr<SkBitmap> bitmap) {
+ void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_TRUE(bitmap);
- callbacks_.push_back(gfx::Size(bitmap->width(), bitmap->height()));
+ EXPECT_TRUE(result->HasBitmap());
+ scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
+ EXPECT_EQ(result->size().ToString(),
+ gfx::Size(bitmap->width(), bitmap->height()).ToString());
+ callbacks_.push_back(result->size());
}
virtual void AfterTest() OVERRIDE {
@@ -2653,11 +2657,13 @@ class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
case 1:
main_destroyed_->RequestCopyOfOutput(
CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestAsyncReadbackLayerDestroyed::BitmapCallback,
+ &LayerTreeHostTestAsyncReadbackLayerDestroyed::
+ CopyOutputCallback,
base::Unretained(this))));
impl_destroyed_->RequestCopyOfOutput(
CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestAsyncReadbackLayerDestroyed::BitmapCallback,
+ &LayerTreeHostTestAsyncReadbackLayerDestroyed::
+ CopyOutputCallback,
base::Unretained(this))));
EXPECT_EQ(0, callback_count_);
@@ -2698,9 +2704,9 @@ class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
}
}
- void BitmapCallback(scoped_ptr<SkBitmap> bitmap) {
+ void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_FALSE(bitmap);
+ EXPECT_TRUE(result->IsEmpty());
++callback_count_;
}