From 691ca62fa359105ef3529d58e8b3205634a88d22 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Fri, 11 Sep 2015 19:40:03 -0700 Subject: [PATCH] Fix for threaded raster readback of texture backed SkImage. This converts texture-backed SkImages of video frames to SkBitmaps so that they can be read back on cc's thread before a SkPicture is handed to raster threads as calling into a GrContext or it's corresponding GLContext is not thread safe. BUG=524717 Review URL: https://codereview.chromium.org/1311783014 Cr-Commit-Position: refs/heads/master@{#348520} --- media/blink/skcanvas_video_renderer.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/media/blink/skcanvas_video_renderer.cc b/media/blink/skcanvas_video_renderer.cc index 14792ff4c47a..3973727c5868 100644 --- a/media/blink/skcanvas_video_renderer.cc +++ b/media/blink/skcanvas_video_renderer.cc @@ -18,6 +18,7 @@ #include "third_party/skia/include/gpu/GrPaint.h" #include "third_party/skia/include/gpu/GrTexture.h" #include "third_party/skia/include/gpu/GrTextureProvider.h" +#include "third_party/skia/include/gpu/SkGr.h" #include "ui/gfx/geometry/rect_f.h" // Skia internal format depends on a platform. On Android it is ABGR, on others @@ -384,7 +385,25 @@ void SkCanvasVideoRenderer::Paint(const scoped_refptr& video_frame, canvas->translate(-SkFloatToScalar(last_image_->width() * 0.5f), -SkFloatToScalar(last_image_->height() * 0.5f)); } - canvas->drawImage(last_image_.get(), 0, 0, &paint); + + // This is a workaround for crbug.com/524717. SkBitmaps are read back before a + // SkPicture is sent to multiple threads while SkImages are not. The long term + // solution is for Skia to provide a SkPicture filter that makes a picture + // safe for multiple CPU raster threads (skbug.com/4321). We limit the + // workaround to cases where the src frame is a texture and the canvas is + // recording. + if (last_image_.get()->getTexture() && + canvas->imageInfo().colorType() == kUnknown_SkColorType) { + SkBitmap bmp; + GrWrapTextureInBitmap(last_image_.get()->getTexture(), + last_image_.get()->width(), last_image_.get()->height(), true, &bmp); + // Even though the bitmap is logically immutable we do not mark it as such + // because doing so would defer readback until rasterization, which will be + // on another thread and is therefore unsafe. + canvas->drawBitmap(bmp, 0, 0, &paint); + } else { + canvas->drawImage(last_image_.get(), 0, 0, &paint); + } if (need_transform) canvas->restore(); -- 2.11.4.GIT