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

Unified Diff: content/renderer/media/android/webmediaplayer_android.cc

Issue 1792563002: Use SkImage rather than SkBitmap in webmediaplayer_android when drawing a video frame (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@baseline
Patch Set: Created 4 years, 6 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 | « content/renderer/media/android/webmediaplayer_android.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/media/android/webmediaplayer_android.cc
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 7adb15e764c5066242f2bc070c7ab1abe9077474..2cca558ec100237d1511ad1e2020d9b74b069182 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -65,10 +65,9 @@
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkTypeface.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/SkGrPixelRef.h"
#include "ui/gfx/image/image.h"
static const uint32_t kGLTextureExternalOES = 0x8D65;
@@ -109,40 +108,6 @@ void OnReleaseTexture(
gl->ShallowFlushCHROMIUM();
}
-bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap,
- const gfx::Size& size) {
- return bitmap->getTexture() && bitmap->width() == size.width() &&
- bitmap->height() == size.height();
-}
-
-bool AllocateSkBitmapTexture(GrContext* gr,
- SkBitmap* bitmap,
- const gfx::Size& size) {
- DCHECK(gr);
- GrTextureDesc desc;
- // Use kRGBA_8888_GrPixelConfig, not kSkia8888_GrPixelConfig, to avoid
- // RGBA to BGRA conversion.
- desc.fConfig = kRGBA_8888_GrPixelConfig;
- // kRenderTarget_GrTextureFlagBit avoids a copy before readback in skia.
- desc.fFlags = kRenderTarget_GrSurfaceFlag;
- desc.fSampleCnt = 0;
- desc.fOrigin = kTopLeft_GrSurfaceOrigin;
- desc.fWidth = size.width();
- desc.fHeight = size.height();
- sk_sp<GrTexture> texture(gr->textureProvider()->refScratchTexture(
- desc, GrTextureProvider::kExact_ScratchTexMatch));
- if (!texture.get())
- return false;
-
- SkImageInfo info = SkImageInfo::MakeN32Premul(desc.fWidth, desc.fHeight);
- SkGrPixelRef* pixel_ref = new SkGrPixelRef(info, texture.get());
- if (!pixel_ref)
- return false;
- bitmap->setInfo(info);
- bitmap->setPixelRef(pixel_ref)->unref();
- return true;
-}
-
class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient {
public:
explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {}
@@ -659,31 +624,40 @@ void WebMediaPlayerAndroid::paint(blink::WebCanvas* canvas,
return;
gpu::gles2::GLES2Interface* gl = provider->contextGL();
- // Copy video texture into a RGBA texture based bitmap first as video texture
- // on Android is GL_TEXTURE_EXTERNAL_OES which is not supported by Skia yet.
- // The bitmap's size needs to be the same as the video and use naturalSize()
- // here. Check if we could reuse existing texture based bitmap.
- // Otherwise, release existing texture based bitmap and allocate
- // a new one based on video size.
- if (!IsSkBitmapProperlySizedTexture(&bitmap_, naturalSize())) {
- if (!AllocateSkBitmapTexture(provider->grContext(), &bitmap_,
- naturalSize())) {
- return;
- }
+ scoped_refptr<VideoFrame> video_frame;
+ {
+ base::AutoLock auto_lock(current_frame_lock_);
+ video_frame = current_frame_;
}
- unsigned textureId = skia::GrBackendObjectToGrGLTextureInfo(
- (bitmap_.getTexture())->getTextureHandle())
- ->fID;
- if (!copyVideoTextureToPlatformTexture(gl, textureId, GL_RGBA,
- GL_UNSIGNED_BYTE, true, false)) {
+ if (!video_frame.get() || !video_frame->HasTextures())
return;
- }
+ DCHECK_EQ(1u, media::VideoFrame::NumPlanes(video_frame->format()));
+ const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0);
+
+ gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());
+
+ uint32_t src_texture = gl->CreateAndConsumeTextureCHROMIUM(
+ mailbox_holder.texture_target, mailbox_holder.mailbox.name);
+
+ GrGLTextureInfo texture_info;
+ texture_info.fID = src_texture;
+ texture_info.fTarget = mailbox_holder.texture_target;
+
+ GrBackendTextureDesc desc;
+ desc.fWidth = naturalSize().width;
+ desc.fHeight = naturalSize().height;
+ desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+ desc.fConfig = kRGBA_8888_GrPixelConfig;
+ desc.fSampleCnt = 0;
+ desc.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(texture_info);
- // Ensure SkBitmap to make the latest change by external source visible.
- bitmap_.notifyPixelsChanged();
+ sk_sp<SkImage> image(SkImage::MakeFromTexture(provider->grContext(), desc,
+ kOpaque_SkAlphaType));
+ if (!image)
+ return;
- // Draw the texture based bitmap onto the Canvas. If the canvas is
+ // Draw the texture based image onto the Canvas. If the canvas is
// hardware based, this will do a GPU-GPU texture copy.
// If the canvas is software based, the texture based bitmap will be
// readbacked to system memory then draw onto the canvas.
@@ -694,8 +668,16 @@ void WebMediaPlayerAndroid::paint(blink::WebCanvas* canvas,
paint.setXfermodeMode(mode);
// It is not necessary to pass the dest into the drawBitmap call since all
// the context have been set up before calling paintCurrentFrameInContext.
- canvas->drawBitmapRect(bitmap_, dest, &paint);
+ canvas->drawImageRect(image, dest, &paint);
+
+ // Ensure the Skia draw of the GL texture is flushed to GL, delete the
+ // mailboxed texture from this context, and then signal that we're done with
+ // the video frame.
canvas->flush();
+ gl->DeleteTextures(1, &src_texture);
+ gl->Flush();
+ SyncTokenClientImpl client(gl);
+ video_frame->UpdateReleaseSyncToken(&client);
}
bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
« no previous file with comments | « content/renderer/media/android/webmediaplayer_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698