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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « content/renderer/media/android/webmediaplayer_android.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/android/webmediaplayer_android.h" 5 #include "content/renderer/media/android/webmediaplayer_android.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" 58 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
59 #include "third_party/WebKit/public/platform/WebMediaPlayerEncryptedMediaClient. h" 59 #include "third_party/WebKit/public/platform/WebMediaPlayerEncryptedMediaClient. h"
60 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" 60 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h"
61 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" 61 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
62 #include "third_party/WebKit/public/platform/WebString.h" 62 #include "third_party/WebKit/public/platform/WebString.h"
63 #include "third_party/WebKit/public/platform/WebURL.h" 63 #include "third_party/WebKit/public/platform/WebURL.h"
64 #include "third_party/WebKit/public/web/WebDocument.h" 64 #include "third_party/WebKit/public/web/WebDocument.h"
65 #include "third_party/WebKit/public/web/WebFrame.h" 65 #include "third_party/WebKit/public/web/WebFrame.h"
66 #include "third_party/WebKit/public/web/WebView.h" 66 #include "third_party/WebKit/public/web/WebView.h"
67 #include "third_party/skia/include/core/SkCanvas.h" 67 #include "third_party/skia/include/core/SkCanvas.h"
68 #include "third_party/skia/include/core/SkImage.h"
68 #include "third_party/skia/include/core/SkPaint.h" 69 #include "third_party/skia/include/core/SkPaint.h"
69 #include "third_party/skia/include/core/SkTypeface.h" 70 #include "third_party/skia/include/core/SkTypeface.h"
70 #include "third_party/skia/include/gpu/GrContext.h"
71 #include "third_party/skia/include/gpu/SkGrPixelRef.h"
72 #include "ui/gfx/image/image.h" 71 #include "ui/gfx/image/image.h"
73 72
74 static const uint32_t kGLTextureExternalOES = 0x8D65; 73 static const uint32_t kGLTextureExternalOES = 0x8D65;
75 static const int kSDKVersionToSupportSecurityOriginCheck = 20; 74 static const int kSDKVersionToSupportSecurityOriginCheck = 20;
76 75
77 using blink::WebMediaPlayer; 76 using blink::WebMediaPlayer;
78 using blink::WebSize; 77 using blink::WebSize;
79 using blink::WebString; 78 using blink::WebString;
80 using blink::WebURL; 79 using blink::WebURL;
81 using gpu::gles2::GLES2Interface; 80 using gpu::gles2::GLES2Interface;
(...skipping 20 matching lines...) Expand all
102 const scoped_refptr<content::StreamTextureFactory>& factories, 101 const scoped_refptr<content::StreamTextureFactory>& factories,
103 uint32_t texture_id, 102 uint32_t texture_id,
104 const gpu::SyncToken& sync_token) { 103 const gpu::SyncToken& sync_token) {
105 GLES2Interface* gl = factories->ContextGL(); 104 GLES2Interface* gl = factories->ContextGL();
106 gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); 105 gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
107 gl->DeleteTextures(1, &texture_id); 106 gl->DeleteTextures(1, &texture_id);
108 // Flush to ensure that the stream texture gets deleted in a timely fashion. 107 // Flush to ensure that the stream texture gets deleted in a timely fashion.
109 gl->ShallowFlushCHROMIUM(); 108 gl->ShallowFlushCHROMIUM();
110 } 109 }
111 110
112 bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap,
113 const gfx::Size& size) {
114 return bitmap->getTexture() && bitmap->width() == size.width() &&
115 bitmap->height() == size.height();
116 }
117
118 bool AllocateSkBitmapTexture(GrContext* gr,
119 SkBitmap* bitmap,
120 const gfx::Size& size) {
121 DCHECK(gr);
122 GrTextureDesc desc;
123 // Use kRGBA_8888_GrPixelConfig, not kSkia8888_GrPixelConfig, to avoid
124 // RGBA to BGRA conversion.
125 desc.fConfig = kRGBA_8888_GrPixelConfig;
126 // kRenderTarget_GrTextureFlagBit avoids a copy before readback in skia.
127 desc.fFlags = kRenderTarget_GrSurfaceFlag;
128 desc.fSampleCnt = 0;
129 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
130 desc.fWidth = size.width();
131 desc.fHeight = size.height();
132 sk_sp<GrTexture> texture(gr->textureProvider()->refScratchTexture(
133 desc, GrTextureProvider::kExact_ScratchTexMatch));
134 if (!texture.get())
135 return false;
136
137 SkImageInfo info = SkImageInfo::MakeN32Premul(desc.fWidth, desc.fHeight);
138 SkGrPixelRef* pixel_ref = new SkGrPixelRef(info, texture.get());
139 if (!pixel_ref)
140 return false;
141 bitmap->setInfo(info);
142 bitmap->setPixelRef(pixel_ref)->unref();
143 return true;
144 }
145
146 class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient { 111 class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient {
147 public: 112 public:
148 explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} 113 explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {}
149 ~SyncTokenClientImpl() override {} 114 ~SyncTokenClientImpl() override {}
150 void GenerateSyncToken(gpu::SyncToken* sync_token) override { 115 void GenerateSyncToken(gpu::SyncToken* sync_token) override {
151 const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM(); 116 const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM();
152 gl_->ShallowFlushCHROMIUM(); 117 gl_->ShallowFlushCHROMIUM();
153 gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData()); 118 gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData());
154 } 119 }
155 void WaitSyncToken(const gpu::SyncToken& sync_token) override { 120 void WaitSyncToken(const gpu::SyncToken& sync_token) override {
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 unsigned char alpha, 617 unsigned char alpha,
653 SkXfermode::Mode mode) { 618 SkXfermode::Mode mode) {
654 DCHECK(main_thread_checker_.CalledOnValidThread()); 619 DCHECK(main_thread_checker_.CalledOnValidThread());
655 std::unique_ptr<blink::WebGraphicsContext3DProvider> provider( 620 std::unique_ptr<blink::WebGraphicsContext3DProvider> provider(
656 blink::Platform::current() 621 blink::Platform::current()
657 ->createSharedOffscreenGraphicsContext3DProvider()); 622 ->createSharedOffscreenGraphicsContext3DProvider());
658 if (!provider) 623 if (!provider)
659 return; 624 return;
660 gpu::gles2::GLES2Interface* gl = provider->contextGL(); 625 gpu::gles2::GLES2Interface* gl = provider->contextGL();
661 626
662 // Copy video texture into a RGBA texture based bitmap first as video texture 627 scoped_refptr<VideoFrame> video_frame;
663 // on Android is GL_TEXTURE_EXTERNAL_OES which is not supported by Skia yet. 628 {
664 // The bitmap's size needs to be the same as the video and use naturalSize() 629 base::AutoLock auto_lock(current_frame_lock_);
665 // here. Check if we could reuse existing texture based bitmap. 630 video_frame = current_frame_;
666 // Otherwise, release existing texture based bitmap and allocate
667 // a new one based on video size.
668 if (!IsSkBitmapProperlySizedTexture(&bitmap_, naturalSize())) {
669 if (!AllocateSkBitmapTexture(provider->grContext(), &bitmap_,
670 naturalSize())) {
671 return;
672 }
673 } 631 }
674 632
675 unsigned textureId = skia::GrBackendObjectToGrGLTextureInfo( 633 if (!video_frame.get() || !video_frame->HasTextures())
676 (bitmap_.getTexture())->getTextureHandle())
677 ->fID;
678 if (!copyVideoTextureToPlatformTexture(gl, textureId, GL_RGBA,
679 GL_UNSIGNED_BYTE, true, false)) {
680 return; 634 return;
681 } 635 DCHECK_EQ(1u, media::VideoFrame::NumPlanes(video_frame->format()));
636 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0);
682 637
683 // Ensure SkBitmap to make the latest change by external source visible. 638 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());
684 bitmap_.notifyPixelsChanged();
685 639
686 // Draw the texture based bitmap onto the Canvas. If the canvas is 640 uint32_t src_texture = gl->CreateAndConsumeTextureCHROMIUM(
641 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
642
643 GrGLTextureInfo texture_info;
644 texture_info.fID = src_texture;
645 texture_info.fTarget = mailbox_holder.texture_target;
646
647 GrBackendTextureDesc desc;
648 desc.fWidth = naturalSize().width;
649 desc.fHeight = naturalSize().height;
650 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
651 desc.fConfig = kRGBA_8888_GrPixelConfig;
652 desc.fSampleCnt = 0;
653 desc.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(texture_info);
654
655 sk_sp<SkImage> image(SkImage::MakeFromTexture(provider->grContext(), desc,
656 kOpaque_SkAlphaType));
657 if (!image)
658 return;
659
660 // Draw the texture based image onto the Canvas. If the canvas is
687 // hardware based, this will do a GPU-GPU texture copy. 661 // hardware based, this will do a GPU-GPU texture copy.
688 // If the canvas is software based, the texture based bitmap will be 662 // If the canvas is software based, the texture based bitmap will be
689 // readbacked to system memory then draw onto the canvas. 663 // readbacked to system memory then draw onto the canvas.
690 SkRect dest; 664 SkRect dest;
691 dest.set(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); 665 dest.set(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
692 SkPaint paint; 666 SkPaint paint;
693 paint.setAlpha(alpha); 667 paint.setAlpha(alpha);
694 paint.setXfermodeMode(mode); 668 paint.setXfermodeMode(mode);
695 // It is not necessary to pass the dest into the drawBitmap call since all 669 // It is not necessary to pass the dest into the drawBitmap call since all
696 // the context have been set up before calling paintCurrentFrameInContext. 670 // the context have been set up before calling paintCurrentFrameInContext.
697 canvas->drawBitmapRect(bitmap_, dest, &paint); 671 canvas->drawImageRect(image, dest, &paint);
672
673 // Ensure the Skia draw of the GL texture is flushed to GL, delete the
674 // mailboxed texture from this context, and then signal that we're done with
675 // the video frame.
698 canvas->flush(); 676 canvas->flush();
677 gl->DeleteTextures(1, &src_texture);
678 gl->Flush();
679 SyncTokenClientImpl client(gl);
680 video_frame->UpdateReleaseSyncToken(&client);
699 } 681 }
700 682
701 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( 683 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
702 gpu::gles2::GLES2Interface* gl, 684 gpu::gles2::GLES2Interface* gl,
703 unsigned int texture, 685 unsigned int texture,
704 unsigned int internal_format, 686 unsigned int internal_format,
705 unsigned int type, 687 unsigned int type,
706 bool premultiply_alpha, 688 bool premultiply_alpha,
707 bool flip_y) { 689 bool flip_y) {
708 DCHECK(main_thread_checker_.CalledOnValidThread()); 690 DCHECK(main_thread_checker_.CalledOnValidThread());
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 result = PREDICTION_RESULT_PATH_BASED_WAS_BETTER; 1662 result = PREDICTION_RESULT_PATH_BASED_WAS_BETTER;
1681 } else if (is_hls_url == is_hls) { 1663 } else if (is_hls_url == is_hls) {
1682 result = PREDICTION_RESULT_URL_BASED_WAS_BETTER; 1664 result = PREDICTION_RESULT_URL_BASED_WAS_BETTER;
1683 } 1665 }
1684 UMA_HISTOGRAM_ENUMERATION( 1666 UMA_HISTOGRAM_ENUMERATION(
1685 "Media.Android.IsHttpLiveStreamingMediaPredictionResult", 1667 "Media.Android.IsHttpLiveStreamingMediaPredictionResult",
1686 result, PREDICTION_RESULT_MAX); 1668 result, PREDICTION_RESULT_MAX);
1687 } 1669 }
1688 1670
1689 } // namespace content 1671 } // namespace content
OLDNEW
« 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