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

Unified Diff: android_webview/browser/in_process_view_renderer.cc

Issue 22799011: [WIP] Import all canvas layers, rather than just topmost (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleaner version (but larger diff) 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
« no previous file with comments | « no previous file | android_webview/public/browser/draw_sw.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: android_webview/browser/in_process_view_renderer.cc
diff --git a/android_webview/browser/in_process_view_renderer.cc b/android_webview/browser/in_process_view_renderer.cc
index 39614d38ce1393af606cafa4e60e686e277382c2..742d89cbf0d325df9e876b2cee624dc4074a5892 100644
--- a/android_webview/browser/in_process_view_renderer.cc
+++ b/android_webview/browser/in_process_view_renderer.cc
@@ -423,79 +423,102 @@ bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas,
web_contents_);
}
-// static
-bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
- jobject java_canvas,
- BrowserViewRenderer::JavaHelper* java_helper,
- const gfx::Vector2d& scroll_correction,
- const gfx::Rect& clip,
- InProcessViewRenderer::RenderMethod render_source,
- void* owner_key) {
- TRACE_EVENT0("android_webview",
- "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded");
-
- JNIEnv* env = AttachCurrentThread();
- ScopedPixelAccess auto_release_pixels(env, java_canvas);
- AwPixelInfo* pixels = auto_release_pixels.pixels();
- SkMatrix matrix;
- SkBitmap::Config config(SkBitmap::kNo_Config);
- if (pixels) {
- switch (pixels->config) {
- case AwConfig_ARGB_8888:
- config = SkBitmap::kARGB_8888_Config;
- break;
- case AwConfig_RGB_565:
- config = SkBitmap::kRGB_565_Config;
- break;
- }
+namespace {
- for (int i = 0; i < 9; i++) {
- matrix.set(i, pixels->matrix[i]);
- }
- // Workaround for http://crbug.com/271096: SW draw only supports
- // translate & scale transforms.
- if (matrix.getType() & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))
- config = SkBitmap::kNo_Config;
- }
-
- if (config == SkBitmap::kNo_Config) {
- // Render into an auxiliary bitmap if pixel info is not available.
- ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas);
- TRACE_EVENT0("android_webview", "RenderToAuxBitmap");
- ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap(
- env, clip.width(), clip.height(), jcanvas, owner_key));
- if (!jbitmap.obj()) {
- TRACE_EVENT_INSTANT0("android_webview",
- "EarlyOut_BitmapAllocFail",
- TRACE_EVENT_SCOPE_THREAD);
+struct LayerImportState {
+ bool SetBitmap(const AwBitmapInfo& info) {
+ SkBitmap::Config config =
+ info.config == AwConfig_ARGB_8888 ? SkBitmap::kARGB_8888_Config :
+ info.config == AwConfig_RGB_565 ? SkBitmap::kRGB_565_Config :
+ SkBitmap::kNo_Config;
+ if (config == SkBitmap::kNo_Config)
return false;
- }
+ bitmap.setConfig(config, info.width, info.height, info.row_bytes);
+ bitmap.setPixels(info.pixels);
- if (!RasterizeIntoBitmap(env, jbitmap,
- clip.x() - scroll_correction.x(),
- clip.y() - scroll_correction.y(),
- render_source)) {
- TRACE_EVENT_INSTANT0("android_webview",
- "EarlyOut_RasterizeFail",
- TRACE_EVENT_SCOPE_THREAD);
- return false;
+ LOG(WARNING) << "JOTH decode: " << info.x << ", " << info.y
+ << ", " << info.width << ", " << info.height;
+ return true;
+ }
+ SkBitmap bitmap;
+ bool importing;
+};
+
+class LayerImportDevice : public SkDevice {
+ public:
+ LayerImportDevice(const LayerImportState* state)
+ : SkDevice(state->bitmap),
+ state_(state) {
+ DCHECK(state_->importing);
+ }
+
+ SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage) {
+ const SkBitmap& bitmap = state_->bitmap;
+ if (!state_->importing) {
+ DCHECK(bitmap.empty() && state_->bitmap.isNull());
+ return new SkDevice(config, width, height, isOpaque);
}
+ DCHECK(usage != SkDevice::kGeneral_Usage);
+ DCHECK(bitmap.config() == config);
+ DCHECK(bitmap.width() == width);
+ DCHECK(bitmap.height() == height);
+ DCHECK(width == 0 || height == 0 || !bitmap.isNull());
+ return new LayerImportDevice(state_);
+ }
- java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas,
- clip.x(), clip.y());
- return true;
+ private:
+ const LayerImportState* state_;
+};
+
+bool RenderDirectToCanvas(JNIEnv* env,
+ jobject java_canvas,
+ BrowserViewRenderer::JavaHelper* java_helper,
+ const gfx::Vector2d& scroll_correction,
+ InProcessViewRenderer::RenderMethod render_source) {
+ ScopedPixelAccess auto_release_pixels(env, java_canvas);
+ AwPixelInfo* pixels = auto_release_pixels.pixels();
+ if (!pixels)
+ return false;
+
+ SkMatrix matrix;
+ for (int i = 0; i < 9; i++) {
+ matrix.set(i, pixels->matrix[i]);
}
+ // Workarounds for http://crbug.com/271096: SW draw only supports
+ // translate & scale transforms, and a simple rectangular clip.
+ if (matrix.getType() & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))
+ return false;
+ if (pixels->clip_rect_count > 1)
+ return false;
// Draw in a SkCanvas built over the pixel information.
- SkBitmap bitmap;
- bitmap.setConfig(config,
- pixels->width,
- pixels->height,
- pixels->row_bytes);
- bitmap.setPixels(pixels->pixels);
- SkDevice device(bitmap);
+ if (pixels->layer_count < 1)
+ return false;
+ LayerImportState layer;
+ layer.importing = true;
+ if (!layer.SetBitmap(pixels->layers[0]))
+ return false;
+ LayerImportDevice device(&layer);
SkCanvas canvas(&device);
- canvas.setMatrix(matrix);
+
+ // Iterate over the layers above the root (hence, starting a 1).
+ for (int i = 1; i < pixels->layer_count; ++i) {
+ const AwBitmapInfo& bitmap = pixels->layers[i];
+ layer.SetBitmap(bitmap);
+ SkRect rect = SkRect::MakeXYWH(bitmap.x, bitmap.y,
+ bitmap.width, bitmap.height);
+ // Use a "dest" xfer so that our shadow-layer stack restore is a no-op.
+ SkPaint dest_mode;
+ dest_mode.setXfermodeMode(SkXfermode::kDst_Mode);
+ canvas.saveLayer(&rect, &dest_mode, SkCanvas::kARGB_NoClipLayer_SaveFlag);
+ DCHECK(canvas.getTopDevice()->getOrigin() ==
+ SkIPoint::Make(bitmap.x, bitmap.y));
+ }
+ layer.bitmap.reset();
+ layer.importing = false;
if (pixels->clip_rect_count) {
SkRegion clip;
@@ -508,13 +531,60 @@ bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
}
canvas.setClipRegion(clip);
}
-
+ canvas.setMatrix(matrix);
canvas.translate(scroll_correction.x(),
scroll_correction.y());
return render_source.Run(&canvas);
}
+} // namespace
+
+bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
+ jobject java_canvas,
+ BrowserViewRenderer::JavaHelper* java_helper,
+ const gfx::Vector2d& scroll_correction,
+ const gfx::Rect& clip,
+ InProcessViewRenderer::RenderMethod render_source,
+ void* owner_key) {
+ TRACE_EVENT0("android_webview",
+ "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded");
+
+ JNIEnv* env = AttachCurrentThread();
+ if (RenderDirectToCanvas(env,
+ java_canvas,
+ java_helper,
+ scroll_correction,
+ render_source)) {
+ return true;
+ }
+ // Render into an auxiliary bitmap if pixel info is not available.
+ ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas);
+ TRACE_EVENT0("android_webview", "RenderToAuxBitmap");
+ ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap(
+ env, clip.width(), clip.height(), jcanvas, owner_key));
+ if (!jbitmap.obj()) {
+ TRACE_EVENT_INSTANT0("android_webview",
+ "EarlyOut_BitmapAllocFail",
+ TRACE_EVENT_SCOPE_THREAD);
+ return false;
+ }
+
+ if (!RasterizeIntoBitmap(env, jbitmap,
+ clip.x() - scroll_correction.x(),
+ clip.y() - scroll_correction.y(),
+ render_source)) {
+ TRACE_EVENT_INSTANT0("android_webview",
+ "EarlyOut_RasterizeFail",
+ TRACE_EVENT_SCOPE_THREAD);
+ return false;
+ }
+
+ java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas,
+ clip.x(), clip.y());
+ return true;
+}
+
skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width,
int height) {
TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture");
« no previous file with comments | « no previous file | android_webview/public/browser/draw_sw.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698