Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1495)

Unified Diff: content/browser/renderer_host/render_widget_host_view_android.cc

Issue 21777003: DevTools: [Android] implement RenderWidgetHostViewAndroid::CopyFromCompositingSurface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments addressed. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/render_widget_host_view_android.cc
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 53a05f24fa4956bde4f2b93542a860a08a10e2d1..e740589afbc93b0b800fe526652caa2ac359e5f0 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -18,6 +18,8 @@
#include "cc/layers/texture_layer.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
#include "cc/trees/layer_tree_host.h"
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/browser/android/content_view_core_impl.h"
@@ -25,6 +27,7 @@
#include "content/browser/android/overscroll_glow.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
+#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/image_transport_factory_android.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/surface_texture_transport_client_android.h"
@@ -34,6 +37,7 @@
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
+#include "skia/ext/image_operations.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/android/device_display_info.h"
@@ -329,8 +333,7 @@ bool RenderWidgetHostViewAndroid::HasFocus() const {
}
bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
- NOTIMPLEMENTED();
- return false;
+ return HasValidFrame();
}
void RenderWidgetHostViewAndroid::Show() {
@@ -540,8 +543,33 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool, const SkBitmap&)>& callback) {
- NOTIMPLEMENTED();
- callback.Run(false, SkBitmap());
+ if (!CanCopyToBitmap()) {
Sami 2013/08/09 16:08:48 Seems like we could just call IsSurfaceAvailableFo
pfeldman 2013/08/09 16:19:59 Done.
+ callback.Run(false, SkBitmap());
+ return;
+ }
+
+ const gfx::Display& display =
+ gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
+ float device_scale_factor = display.device_scale_factor();
+
+ const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
+ gfx::Rect src_subrect_in_pixel =
+ ConvertRectToPixel(device_scale_factor, src_subrect);
+
+ scoped_ptr<cc::CopyOutputRequest> request;
+ if (src_subrect_in_pixel.size() == dst_size_in_pixel) {
+ request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
+ &RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceHasResult,
+ dst_size_in_pixel,
+ callback));
+ } else {
+ request = cc::CopyOutputRequest::CreateRequest(base::Bind(
+ &RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceHasResult,
+ dst_size_in_pixel,
+ callback));
+ }
+ request->set_area(src_subrect_in_pixel);
+ layer_->RequestCopyOfOutput(request.Pass());
}
void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
@@ -552,6 +580,10 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
callback.Run(false);
}
+bool RenderWidgetHostViewAndroid::CanCopyToBitmap() const {
+ return true;
Sami 2013/08/09 16:08:48 Do we need this method? Please add a TODO if somet
pfeldman 2013/08/09 16:19:59 Removed
+}
+
bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
return false;
}
@@ -1153,6 +1185,110 @@ void RenderWidgetHostViewAndroid::OnLostResources() {
}
// static
+void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceHasResult(
+ const gfx::Size& dst_size_in_pixel,
+ const base::Callback<void(bool, const SkBitmap&)>& callback,
+ scoped_ptr<cc::CopyOutputResult> result) {
+ if (result->IsEmpty() || result->size().IsEmpty()) {
+ callback.Run(false, SkBitmap());
+ return;
+ }
+
+ if (result->HasTexture()) {
+ PrepareTextureCopyOutputResult(dst_size_in_pixel, callback, result.Pass());
+ return;
+ }
+
+ DCHECK(result->HasBitmap());
+ PrepareBitmapCopyOutputResult(dst_size_in_pixel, callback, result.Pass());
+}
+
+static void CopyFromCompositingSurfaceFinished(
+ const base::Callback<void(bool, const SkBitmap&)>& callback,
+ const cc::TextureMailbox::ReleaseCallback& release_callback,
+ scoped_ptr<SkBitmap> bitmap,
+ scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
+ bool result) {
+ bitmap_pixels_lock.reset();
+ release_callback.Run(0, false);
+ callback.Run(result, *bitmap);
+}
+
+// static
+void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
+ const gfx::Size& dst_size_in_pixel,
+ const base::Callback<void(bool, const SkBitmap&)>& callback,
+ scoped_ptr<cc::CopyOutputResult> result) {
+ base::ScopedClosureRunner scoped_callback_runner(
+ base::Bind(callback, false, SkBitmap()));
+
+ DCHECK(result->HasTexture());
+ if (!result->HasTexture())
+ return;
+
+ scoped_ptr<SkBitmap> bitmap(new SkBitmap);
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config,
+ dst_size_in_pixel.width(), dst_size_in_pixel.height());
+ if (!bitmap->allocPixels())
+ return;
+ bitmap->setIsOpaque(true);
+
+ ImageTransportFactoryAndroid* factory =
+ ImageTransportFactoryAndroid::GetInstance();
+ GLHelper* gl_helper = factory->GetGLHelper();
+ if (!gl_helper)
+ return;
+
+ scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
+ new SkAutoLockPixels(*bitmap));
+ uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
+
+ scoped_ptr<cc::TextureMailbox> texture_mailbox = result->TakeTexture();
+ DCHECK(texture_mailbox->IsTexture());
+ if (!texture_mailbox->IsTexture())
+ return;
+
+ scoped_callback_runner.Release();
+
+ gl_helper->CropScaleReadbackAndCleanMailbox(
+ texture_mailbox->name(),
+ texture_mailbox->sync_point(),
+ result->size(),
+ gfx::Rect(result->size()),
+ dst_size_in_pixel,
+ pixels,
+ base::Bind(&CopyFromCompositingSurfaceFinished,
+ callback,
+ texture_mailbox->callback(),
+ base::Passed(&bitmap),
+ base::Passed(&bitmap_pixels_lock)));
+}
+
+// static
+void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
+ const gfx::Size& dst_size_in_pixel,
+ const base::Callback<void(bool, const SkBitmap&)>& callback,
+ scoped_ptr<cc::CopyOutputResult> result) {
+ DCHECK(result->HasBitmap());
+
+ base::ScopedClosureRunner scoped_callback_runner(
+ base::Bind(callback, false, SkBitmap()));
+ if (!result->HasBitmap())
+ return;
+
+ scoped_ptr<SkBitmap> source = result->TakeBitmap();
+ DCHECK(source);
+ if (!source)
+ return;
+
+ DCHECK_EQ(source->width(), dst_size_in_pixel.width());
+ DCHECK_EQ(source->height(), dst_size_in_pixel.height());
+
+ scoped_callback_runner.Release();
+ callback.Run(true, *source);
+}
+
+// static
void RenderWidgetHostViewPort::GetDefaultScreenInfo(
WebKit::WebScreenInfo* results) {
const gfx::Display& display =

Powered by Google App Engine
This is Rietveld 408576698