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

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: Using RequestCopyOfOutput async API. 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..7ab263759cf1294dfea919cab170536bf89a906f 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"
@@ -276,6 +280,36 @@ bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
return true;
}
+bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(
no sievers 2013/08/07 18:41:43 So this is unneeded then?
pfeldman 2013/08/09 13:59:02 Correct. Removed.
+ const gfx::Size& size, SkBitmap* bitmap) {
+ if (!CompositorImpl::IsInitialized() ||
+ texture_id_in_layer_ == 0 ||
+ texture_size_in_layer_.IsEmpty())
+ return false;
+
+ GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
+
+ WebKit::WebGLId texture = helper->CopyAndScaleTexture(
+ texture_id_in_layer_,
+ texture_size_in_layer_,
+ size,
+ true,
+ GLHelper::SCALER_QUALITY_FAST);
+ if (texture == 0)
+ return false;
+
+ helper->ReadbackTextureSync(
+ texture,
+ gfx::Rect(size),
+ static_cast<unsigned char*> (bitmap->getPixels()));
+
+ WebKit::WebGraphicsContext3D* context =
+ ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
+ context->deleteTexture(texture);
+
+ return true;
+}
+
bool RenderWidgetHostViewAndroid::HasValidFrame() const {
return texture_id_in_layer_ != 0 &&
content_view_core_ &&
@@ -540,8 +574,21 @@ 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()) {
+ callback.Run(false, SkBitmap());
+ return;
+ }
+
+ const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
+ scoped_ptr<cc::CopyOutputRequest> request =
+ cc::CopyOutputRequest::CreateRequest(base::Bind(
no sievers 2013/08/07 19:51:28 Should this create a bitmap request if we don't ha
Sami 2013/08/08 11:35:00 Yeah, no need to make a redundant copy in that cas
pfeldman 2013/08/09 13:59:02 Done.
+ &RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceHasResult,
+ dst_size_in_pixel,
+ callback));
+ gfx::Rect src_subrect_in_pixel =
+ ConvertRectToPixel(current_device_scale_factor_, src_subrect);
+ request->set_area(src_subrect_in_pixel);
+ layer_->RequestCopyOfOutput(request.Pass());
}
void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
@@ -552,6 +599,10 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
callback.Run(false);
}
+bool RenderWidgetHostViewAndroid::CanCopyToBitmap() const {
+ return true;
+}
+
bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
return false;
}
@@ -1153,6 +1204,113 @@ 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;
+
+ scoped_callback_runner.Release();
+
+ SkBitmap bitmap = skia::ImageOperations::Resize(
no sievers 2013/08/07 19:51:28 Let's remove this and dcheck() that the dimensions
pfeldman 2013/08/09 13:59:02 Done.
+ *source,
+ skia::ImageOperations::RESIZE_BEST,
+ dst_size_in_pixel.width(),
+ dst_size_in_pixel.height());
+ callback.Run(true, bitmap);
+}
+
+// static
void RenderWidgetHostViewPort::GetDefaultScreenInfo(
WebKit::WebScreenInfo* results) {
const gfx::Display& display =

Powered by Google App Engine
This is Rietveld 408576698