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 f5dd958ba5c10fd7a5cce1640997d7ee6dcfd3a0..61cd4f8c9dbfc25d870d868bf6a67da35497d058 100644 |
--- a/content/renderer/media/android/webmediaplayer_android.cc |
+++ b/content/renderer/media/android/webmediaplayer_android.cc |
@@ -39,8 +39,7 @@ |
#include "media/base/media_switches.h" |
#include "media/base/video_frame.h" |
#include "net/base/mime_util.h" |
-#include "third_party/WebKit/public/platform/Platform.h" |
-#include "third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h" |
+#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" |
#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" |
#include "third_party/WebKit/public/platform/WebString.h" |
#include "third_party/WebKit/public/platform/WebURL.h" |
@@ -49,10 +48,12 @@ |
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
#include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
#include "third_party/WebKit/public/web/WebView.h" |
+#include "third_party/skia/include/core/SkBitmap.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
-#include "third_party/skia/include/core/SkPaint.h" |
#include "third_party/skia/include/core/SkTypeface.h" |
#include "ui/gfx/image/image.h" |
+#include "webkit/common/gpu/context_provider_web_context.h" |
+#include "webkit/common/gpu/webgraphicscontext3d_impl.h" |
static const uint32 kGLTextureExternalOES = 0x8D65; |
@@ -79,23 +80,6 @@ void OnReleaseTexture( |
gl->DeleteTextures(1, &texture_id); |
} |
-class SyncPointClientImpl : public media::VideoFrame::SyncPointClient { |
- public: |
- explicit SyncPointClientImpl( |
- blink::WebGraphicsContext3D* web_graphics_context) |
- : web_graphics_context_(web_graphics_context) {} |
- virtual ~SyncPointClientImpl() {} |
- virtual uint32 InsertSyncPoint() OVERRIDE { |
- return web_graphics_context_->insertSyncPoint(); |
- } |
- virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE { |
- web_graphics_context_->waitSyncPoint(sync_point); |
- } |
- |
- private: |
- blink::WebGraphicsContext3D* web_graphics_context_; |
-}; |
- |
} // namespace |
namespace content { |
@@ -461,79 +445,26 @@ bool WebMediaPlayerAndroid::didLoadingProgress() { |
return ret; |
} |
-bool WebMediaPlayerAndroid::EnsureTextureBackedSkBitmap(GrContext* gr, |
- SkBitmap& bitmap, |
- const WebSize& size, |
- GrSurfaceOrigin origin, |
- GrPixelConfig config) { |
- if (!bitmap.getTexture() || bitmap.width() != size.width |
- || bitmap.height() != size.height) { |
- if (!gr) |
- return false; |
- GrTextureDesc desc; |
- desc.fConfig = config; |
- desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
- desc.fSampleCnt = 0; |
- desc.fOrigin = origin; |
- desc.fWidth = size.width; |
- desc.fHeight = size.height; |
- skia::RefPtr<GrTexture> texture; |
- texture = skia::AdoptRef(gr->createUncachedTexture(desc, 0, 0)); |
- if (!texture.get()) |
- return false; |
- |
- SkImageInfo info = SkImageInfo::MakeN32Premul(desc.fWidth, desc.fHeight); |
- SkGrPixelRef* pixelRef = SkNEW_ARGS(SkGrPixelRef, (info, texture.get())); |
- if (!pixelRef) |
- return false; |
- bitmap.setInfo(info); |
- bitmap.setPixelRef(pixelRef)->unref(); |
- } |
- |
- return true; |
-} |
- |
void WebMediaPlayerAndroid::paint(blink::WebCanvas* canvas, |
const blink::WebRect& rect, |
unsigned char alpha) { |
- scoped_ptr<blink::WebGraphicsContext3DProvider> provider = |
- scoped_ptr<blink::WebGraphicsContext3DProvider>(blink::Platform::current( |
- )->createSharedOffscreenGraphicsContext3DProvider()); |
- if (!provider) |
- return; |
- blink::WebGraphicsContext3D* context3D = provider->context3d(); |
- if (!context3D || !context3D->makeContextCurrent()) |
- return; |
- |
- // 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 (!EnsureTextureBackedSkBitmap(provider->grContext(), bitmap_, |
- naturalSize(), kTopLeft_GrSurfaceOrigin, kSkia8888_GrPixelConfig)) { |
+ // Don't allow clients to copy an encrypted video frame. |
+ if (needs_external_surface_) |
return; |
- } |
- unsigned textureId = static_cast<unsigned>( |
- (bitmap_.getTexture())->getTextureHandle()); |
- if (!copyVideoTextureToPlatformTexture(context3D, textureId, 0, |
- GL_RGBA, GL_UNSIGNED_BYTE, true, false)) { |
- return; |
+ scoped_refptr<VideoFrame> video_frame; |
+ { |
+ base::AutoLock auto_lock(current_frame_lock_); |
+ video_frame = current_frame_; |
} |
- // Draw the texture based bitmap 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. |
- SkRect dest; |
- dest.set(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); |
- SkPaint paint; |
- paint.setAlpha(alpha); |
- // 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_, 0, dest, &paint); |
+ gfx::Rect gfx_rect(rect); |
+ scoped_refptr<cc::ContextProvider> context_provider = |
+ RenderThreadImpl::current()->SharedMainThreadContextProvider(); |
+ media::SkCanvasVideoRenderer::ContextProvider provider{ |
+ context_provider->ContextGL(), context_provider->GrContext()}; |
+ skcanvas_video_renderer_.Paint( |
+ video_frame.get(), canvas, gfx_rect, alpha, &provider); |
} |
bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( |
@@ -557,10 +488,13 @@ bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( |
if (!video_frame || |
video_frame->format() != media::VideoFrame::NATIVE_TEXTURE) |
return false; |
+ |
+#if DCHECK_IS_ON |
const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder(); |
DCHECK((!is_remote_ && |
mailbox_holder->texture_target == GL_TEXTURE_EXTERNAL_OES) || |
(is_remote_ && mailbox_holder->texture_target == GL_TEXTURE_2D)); |
+#endif |
// For hidden video element (with style "display:none"), ensure the texture |
// size is set. |
@@ -572,35 +506,19 @@ bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( |
cached_stream_texture_size_ = natural_size_; |
} |
- web_graphics_context->waitSyncPoint(mailbox_holder->sync_point); |
- |
- // Ensure the target of texture is set before copyTextureCHROMIUM, otherwise |
- // an invalid texture target may be used for copy texture. |
- uint32 src_texture = web_graphics_context->createAndConsumeTextureCHROMIUM( |
- mailbox_holder->texture_target, mailbox_holder->mailbox.name); |
- |
- // The video is stored in an unmultiplied format, so premultiply if |
- // necessary. |
- web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, |
- premultiply_alpha); |
- |
- // Application itself needs to take care of setting the right flip_y |
- // value down to get the expected result. |
- // flip_y==true means to reverse the video orientation while |
- // flip_y==false means to keep the intrinsic orientation. |
- web_graphics_context->pixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); |
- web_graphics_context->copyTextureCHROMIUM(GL_TEXTURE_2D, src_texture, |
- texture, level, internal_format, |
- type); |
- web_graphics_context->pixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, false); |
- web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, |
- false); |
- |
- web_graphics_context->deleteTexture(src_texture); |
- web_graphics_context->flush(); |
- |
- SyncPointClientImpl client(web_graphics_context); |
- video_frame->UpdateReleaseSyncPoint(&client); |
+ // TODO(dshwang): need more elegant way to convert WebGraphicsContext3D to |
+ // GLES2Interface. |
+ gpu::gles2::GLES2Interface* gl = |
+ static_cast<webkit::gpu::WebGraphicsContext3DImpl*>(web_graphics_context) |
+ ->GetGLInterface(); |
+ skcanvas_video_renderer_.CopyVideoFrameToTexture(gl, |
+ video_frame.get(), |
+ texture, |
+ level, |
+ internal_format, |
+ type, |
+ premultiply_alpha, |
+ flip_y); |
return true; |
} |