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

Side by Side Diff: media/blink/skcanvas_video_renderer.cc

Issue 1144323003: media: Refactor SkCanvasVideoRenderer to use SkImages and not SkBitmaps. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use skia::RefPtr. Log texture_target in the DCHECK. Created 5 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 | « media/blink/skcanvas_video_renderer.h ('k') | media/blink/skcanvas_video_renderer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/blink/skcanvas_video_renderer.h" 5 #include "media/blink/skcanvas_video_renderer.h"
6 6
7 #include "gpu/GLES2/gl2extchromium.h" 7 #include "gpu/GLES2/gl2extchromium.h"
8 #include "gpu/command_buffer/client/gles2_interface.h" 8 #include "gpu/command_buffer/client/gles2_interface.h"
9 #include "gpu/command_buffer/common/mailbox_holder.h" 9 #include "gpu/command_buffer/common/mailbox_holder.h"
10 #include "media/base/video_frame.h" 10 #include "media/base/video_frame.h"
11 #include "media/base/yuv_convert.h" 11 #include "media/base/yuv_convert.h"
12 #include "skia/ext/refptr.h" 12 #include "skia/ext/refptr.h"
13 #include "third_party/libyuv/include/libyuv.h" 13 #include "third_party/libyuv/include/libyuv.h"
14 #include "third_party/skia/include/core/SkCanvas.h" 14 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "third_party/skia/include/core/SkImage.h"
15 #include "third_party/skia/include/core/SkImageGenerator.h" 16 #include "third_party/skia/include/core/SkImageGenerator.h"
16 #include "third_party/skia/include/gpu/GrContext.h" 17 #include "third_party/skia/include/gpu/GrContext.h"
17 #include "third_party/skia/include/gpu/GrTextureProvider.h" 18 #include "third_party/skia/include/gpu/GrTextureProvider.h"
18 #include "third_party/skia/include/gpu/SkGrPixelRef.h" 19 #include "third_party/skia/include/gpu/SkGrPixelRef.h"
19 #include "ui/gfx/skbitmap_operations.h"
20 20
21 // Skia internal format depends on a platform. On Android it is ABGR, on others 21 // Skia internal format depends on a platform. On Android it is ABGR, on others
22 // it is ARGB. 22 // it is ARGB.
23 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \ 23 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \
24 SK_A32_SHIFT == 24 24 SK_A32_SHIFT == 24
25 #define LIBYUV_I420_TO_ARGB libyuv::I420ToARGB 25 #define LIBYUV_I420_TO_ARGB libyuv::I420ToARGB
26 #define LIBYUV_I422_TO_ARGB libyuv::I422ToARGB 26 #define LIBYUV_I422_TO_ARGB libyuv::I422ToARGB
27 #elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \ 27 #elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
28 SK_A32_SHIFT == 24 28 SK_A32_SHIFT == 24
29 #define LIBYUV_I420_TO_ARGB libyuv::I420ToABGR 29 #define LIBYUV_I420_TO_ARGB libyuv::I420ToABGR
30 #define LIBYUV_I422_TO_ARGB libyuv::I422ToABGR 30 #define LIBYUV_I422_TO_ARGB libyuv::I422ToABGR
31 #else 31 #else
32 #error Unexpected Skia ARGB_8888 layout! 32 #error Unexpected Skia ARGB_8888 layout!
33 #endif 33 #endif
34 34
35 namespace media { 35 namespace media {
36 36
37 namespace { 37 namespace {
38 38
39 // This class keeps two temporary resources; software bitmap, hardware bitmap. 39 bool IsCanvasDrawingOnPicture(SkCanvas* canvas) {
40 // If both bitmap are created and then only software bitmap is updated every 40 SkImageInfo info;
41 // frame, hardware bitmap outlives until the media player dies. So we delete 41 size_t rowBytes;
42 // a temporary resource if it is not used for 3 sec. 42 return !canvas->getGrContext() && !canvas->peekPixels(&info, &rowBytes);
43 const int kTemporaryResourceDeletionDelay = 3; // Seconds; 43 }
44 44
45 bool IsYUV(media::VideoFrame::Format format) { 45 bool IsYUV(media::VideoFrame::Format format) {
46 switch (format) { 46 switch (format) {
47 case VideoFrame::YV12: 47 case VideoFrame::YV12:
48 case VideoFrame::YV16: 48 case VideoFrame::YV16:
49 case VideoFrame::I420: 49 case VideoFrame::I420:
50 case VideoFrame::YV12A: 50 case VideoFrame::YV12A:
51 case VideoFrame::YV24: 51 case VideoFrame::YV24:
52 case VideoFrame::NV12: 52 case VideoFrame::NV12:
53 return true; 53 return true;
(...skipping 14 matching lines...) Expand all
68 int result; 68 int result;
69 return video_frame->metadata()->GetInteger( 69 return video_frame->metadata()->GetInteger(
70 media::VideoFrameMetadata::COLOR_SPACE, &result) && 70 media::VideoFrameMetadata::COLOR_SPACE, &result) &&
71 result == color_space; 71 result == color_space;
72 } 72 }
73 73
74 bool IsYUVOrNative(media::VideoFrame::Format format) { 74 bool IsYUVOrNative(media::VideoFrame::Format format) {
75 return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE; 75 return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE;
76 } 76 }
77 77
78 bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap,
79 const gfx::Size& size) {
80 return bitmap->getTexture() && bitmap->width() == size.width() &&
81 bitmap->height() == size.height();
82 }
83
84 bool AllocateSkBitmapTexture(GrContext* gr,
85 SkBitmap* bitmap,
86 const gfx::Size& size) {
87 DCHECK(gr);
88 GrTextureDesc desc;
89 // Use kRGBA_8888_GrPixelConfig, not kSkia8888_GrPixelConfig, to avoid
90 // RGBA to BGRA conversion.
91 desc.fConfig = kRGBA_8888_GrPixelConfig;
92 desc.fFlags = kRenderTarget_GrSurfaceFlag;
93 desc.fSampleCnt = 0;
94 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
95 desc.fWidth = size.width();
96 desc.fHeight = size.height();
97 skia::RefPtr<GrTexture> texture = skia::AdoptRef(
98 gr->textureProvider()->refScratchTexture(
99 desc, GrTextureProvider::kExact_ScratchTexMatch));
100 if (!texture.get())
101 return false;
102
103 SkImageInfo info = SkImageInfo::MakeN32Premul(desc.fWidth, desc.fHeight);
104 SkGrPixelRef* pixel_ref = SkNEW_ARGS(SkGrPixelRef, (info, texture.get()));
105 if (!pixel_ref)
106 return false;
107 bitmap->setInfo(info);
108 bitmap->setPixelRef(pixel_ref)->unref();
109 return true;
110 }
111
112 bool CopyVideoFrameTextureToSkBitmapTexture(VideoFrame* video_frame,
113 SkBitmap* bitmap,
114 const Context3D& context_3d) {
115 // Check if we could reuse existing texture based bitmap.
116 // Otherwise, release existing texture based bitmap and allocate
117 // a new one based on video size.
118 if (!IsSkBitmapProperlySizedTexture(bitmap,
119 video_frame->visible_rect().size())) {
120 if (!AllocateSkBitmapTexture(context_3d.gr_context, bitmap,
121 video_frame->visible_rect().size())) {
122 return false;
123 }
124 }
125
126 unsigned texture_id =
127 static_cast<unsigned>((bitmap->getTexture())->getTextureHandle());
128 // If CopyVideoFrameTextureToGLTexture() changes the state of the
129 // |texture_id|, it's needed to invalidate the state cached in skia,
130 // but currently the state isn't changed.
131 SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture(
132 context_3d.gl, video_frame, texture_id, GL_RGBA, GL_UNSIGNED_BYTE, true,
133 false);
134 bitmap->notifyPixelsChanged();
135 return true;
136 }
137
138 class SyncPointClientImpl : public VideoFrame::SyncPointClient { 78 class SyncPointClientImpl : public VideoFrame::SyncPointClient {
139 public: 79 public:
140 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} 80 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {}
141 ~SyncPointClientImpl() override {} 81 ~SyncPointClientImpl() override {}
142 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); } 82 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); }
143 void WaitSyncPoint(uint32 sync_point) override { 83 void WaitSyncPoint(uint32 sync_point) override {
144 gl_->WaitSyncPointCHROMIUM(sync_point); 84 gl_->WaitSyncPointCHROMIUM(sync_point);
145 } 85 }
146 86
147 private: 87 private:
148 gpu::gles2::GLES2Interface* gl_; 88 gpu::gles2::GLES2Interface* gl_;
149 89
150 DISALLOW_IMPLICIT_CONSTRUCTORS(SyncPointClientImpl); 90 DISALLOW_IMPLICIT_CONSTRUCTORS(SyncPointClientImpl);
151 }; 91 };
152 92
93 // Creates a SkImage from a |video_frame| backed by native resources.
94 // The SkImage will not take ownership of the underlying resources and the
95 // caller will have to delete them after the SkImage is used.
96 // |source_textures| is a pointer to an array that will be filled with
97 // texture ids backing the returned image.
98 skia::RefPtr<SkImage> NewSkImageFromVideoFrameNative(
99 const scoped_refptr<VideoFrame>& video_frame,
100 const Context3D& context_3d,
101 unsigned* source_textures) {
102 // TODO(dcastagna): Add support for YUV420.
103 DCHECK_EQ(VideoFrame::TEXTURE_RGBA, video_frame->texture_format());
104
105 // Get the texture from the mailbox and wrap it in a GrTexture.
106 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0);
107 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D ||
108 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB ||
109 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES)
dshwang 2015/05/29 08:49:47 Can SkImage wrap RECTANBLE_ARB and EXTERNAL_OES al
dshwang 2015/05/29 17:30:30 skia doesn't support RECTANBLE_ARB and EXTERNAL_OE
Daniele Castagna 2015/06/05 04:15:31 This happened to work for texture_rectangle. :/ Br
110 << mailbox_holder.texture_target;
111 gpu::gles2::GLES2Interface* gl = context_3d.gl;
112 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point);
113 *source_textures = gl->CreateAndConsumeTextureCHROMIUM(
114 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
115 GrBackendTextureDesc desc;
116 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
117 desc.fWidth = video_frame->coded_size().width();
118 desc.fHeight = video_frame->coded_size().height();
119 desc.fConfig = kRGBA_8888_GrPixelConfig;
120 desc.fTextureHandle = *source_textures;
121 return skia::AdoptRef(SkImage::NewFromTexture(context_3d.gr_context, desc));
122 }
123
153 } // anonymous namespace 124 } // anonymous namespace
154 125
155 // Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU. 126 // Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU.
156 class VideoImageGenerator : public SkImageGenerator { 127 class VideoImageGenerator : public SkImageGenerator {
157 public: 128 public:
158 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) 129 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame)
159 : SkImageGenerator( 130 : SkImageGenerator(
160 SkImageInfo::MakeN32Premul(frame->visible_rect().width(), 131 SkImageInfo::MakeN32Premul(frame->visible_rect().width(),
161 frame->visible_rect().height())) 132 frame->visible_rect().height()))
162 , frame_(frame) { 133 , frame_(frame) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 } 219 }
249 return true; 220 return true;
250 } 221 }
251 222
252 private: 223 private:
253 scoped_refptr<VideoFrame> frame_; 224 scoped_refptr<VideoFrame> frame_;
254 225
255 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoImageGenerator); 226 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoImageGenerator);
256 }; 227 };
257 228
258 SkCanvasVideoRenderer::SkCanvasVideoRenderer() 229 SkCanvasVideoRenderer::SkCanvasVideoRenderer() {
259 : last_frame_timestamp_(media::kNoTimestamp()),
260 frame_deleting_timer_(
261 FROM_HERE,
262 base::TimeDelta::FromSeconds(kTemporaryResourceDeletionDelay),
263 this,
264 &SkCanvasVideoRenderer::ResetLastFrame),
265 accelerated_generator_(nullptr),
266 accelerated_last_frame_timestamp_(media::kNoTimestamp()),
267 accelerated_frame_deleting_timer_(
268 FROM_HERE,
269 base::TimeDelta::FromSeconds(kTemporaryResourceDeletionDelay),
270 this,
271 &SkCanvasVideoRenderer::ResetAcceleratedLastFrame) {
272 last_frame_.setIsVolatile(true);
273 } 230 }
274 231
275 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {} 232 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {
233 }
276 234
277 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, 235 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame,
278 SkCanvas* canvas, 236 SkCanvas* canvas,
279 const gfx::RectF& dest_rect, 237 const gfx::RectF& dest_rect,
280 uint8 alpha, 238 uint8 alpha,
281 SkXfermode::Mode mode, 239 SkXfermode::Mode mode,
282 VideoRotation video_rotation, 240 VideoRotation video_rotation,
283 const Context3D& context_3d) { 241 const Context3D& context_3d) {
284 if (alpha == 0) { 242 if (alpha == 0) {
285 return; 243 return;
286 } 244 }
287 245
288 SkRect dest; 246 SkRect dest;
289 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); 247 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom());
290 248
291 SkPaint paint; 249 SkPaint paint;
292 paint.setAlpha(alpha); 250 paint.setAlpha(alpha);
293 251
294 // Paint black rectangle if there isn't a frame available or the 252 // Paint black rectangle if there isn't a frame available or the
295 // frame has an unexpected format. 253 // frame has an unexpected format.
296 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || 254 if (!video_frame.get() || video_frame->natural_size().IsEmpty() ||
297 !IsYUVOrNative(video_frame->format())) { 255 !IsYUVOrNative(video_frame->format())) {
298 canvas->drawRect(dest, paint); 256 canvas->drawRect(dest, paint);
299 canvas->flush(); 257 canvas->flush();
300 return; 258 return;
301 } 259 }
302 260
303 SkBitmap* target_frame = nullptr; 261 unsigned texture_id = 0;
304 262 skia::RefPtr<SkImage> target_frame;
305 if (video_frame->format() == VideoFrame::NATIVE_TEXTURE) { 263 if (video_frame->format() == VideoFrame::NATIVE_TEXTURE) {
306 // Draw HW Video on both SW and HW Canvas. 264 DCHECK(context_3d.gr_context);
307 // In SW Canvas case, rely on skia drawing Ganesh SkBitmap on SW SkCanvas. 265 DCHECK(context_3d.gl);
308 if (accelerated_last_frame_.isNull() || 266 target_frame =
309 video_frame->timestamp() != accelerated_last_frame_timestamp_) { 267 NewSkImageFromVideoFrameNative(video_frame, context_3d, &texture_id);
310 DCHECK(context_3d.gl);
311 DCHECK(context_3d.gr_context);
312 if (accelerated_generator_) {
313 // Reset SkBitmap used in SWVideo-to-HWCanvas path.
314 accelerated_last_frame_.reset();
315 accelerated_generator_ = nullptr;
316 }
317 if (!CopyVideoFrameTextureToSkBitmapTexture(
318 video_frame.get(), &accelerated_last_frame_, context_3d)) {
319 NOTREACHED();
320 return;
321 }
322 DCHECK(video_frame->visible_rect().width() ==
323 accelerated_last_frame_.width() &&
324 video_frame->visible_rect().height() ==
325 accelerated_last_frame_.height());
326
327 accelerated_last_frame_timestamp_ = video_frame->timestamp();
328 }
329 target_frame = &accelerated_last_frame_;
330 accelerated_frame_deleting_timer_.Reset();
331 } else if (canvas->getGrContext()) {
332 DCHECK(video_frame->format() != VideoFrame::NATIVE_TEXTURE);
333 if (accelerated_last_frame_.isNull() ||
334 video_frame->timestamp() != accelerated_last_frame_timestamp_) {
335 // Draw SW Video on HW Canvas.
336 if (!accelerated_generator_ && !accelerated_last_frame_.isNull()) {
337 // Reset SkBitmap used in HWVideo-to-HWCanvas path.
338 accelerated_last_frame_.reset();
339 }
340 accelerated_generator_ = new VideoImageGenerator(video_frame);
341
342 // Note: This takes ownership of |accelerated_generator_|.
343 if (!SkInstallDiscardablePixelRef(accelerated_generator_,
344 &accelerated_last_frame_)) {
345 NOTREACHED();
346 return;
347 }
348 DCHECK(video_frame->visible_rect().width() ==
349 accelerated_last_frame_.width() &&
350 video_frame->visible_rect().height() ==
351 accelerated_last_frame_.height());
352
353 accelerated_last_frame_timestamp_ = video_frame->timestamp();
354 } else if (accelerated_generator_) {
355 accelerated_generator_->set_frame(video_frame);
356 }
357 target_frame = &accelerated_last_frame_;
358 accelerated_frame_deleting_timer_.Reset();
359 } else { 268 } else {
360 // Draw SW Video on SW Canvas. 269 VideoImageGenerator* generator = new VideoImageGenerator(video_frame);
361 DCHECK(video_frame->format() != VideoFrame::NATIVE_TEXTURE); 270 target_frame = skia::AdoptRef(SkImage::NewFromGenerator(generator));
362 if (last_frame_.isNull() ||
363 video_frame->timestamp() != last_frame_timestamp_) {
364 // Check if |bitmap| needs to be (re)allocated.
365 if (last_frame_.isNull() ||
366 last_frame_.width() != video_frame->visible_rect().width() ||
367 last_frame_.height() != video_frame->visible_rect().height()) {
368 last_frame_.allocN32Pixels(video_frame->visible_rect().width(),
369 video_frame->visible_rect().height());
370 last_frame_.setIsVolatile(true);
371 }
372 last_frame_.lockPixels();
373 ConvertVideoFrameToRGBPixels(
374 video_frame, last_frame_.getPixels(), last_frame_.rowBytes());
375 last_frame_.notifyPixelsChanged();
376 last_frame_.unlockPixels();
377 last_frame_timestamp_ = video_frame->timestamp();
378 }
379 target_frame = &last_frame_;
380 frame_deleting_timer_.Reset();
381 } 271 }
382 272
383 paint.setXfermodeMode(mode); 273 paint.setXfermodeMode(mode);
384 paint.setFilterQuality(kLow_SkFilterQuality); 274 paint.setFilterQuality(kLow_SkFilterQuality);
385 275
386 bool need_transform = 276 bool need_transform =
387 video_rotation != VIDEO_ROTATION_0 || 277 video_rotation != VIDEO_ROTATION_0 ||
388 dest_rect.size() != video_frame->visible_rect().size() || 278 dest_rect.size() != video_frame->visible_rect().size() ||
389 !dest_rect.origin().IsOrigin(); 279 !dest_rect.origin().IsOrigin();
390 if (need_transform) { 280 if (need_transform) {
(...skipping 22 matching lines...) Expand all
413 video_rotation == VIDEO_ROTATION_270) { 303 video_rotation == VIDEO_ROTATION_270) {
414 rotated_dest_size = 304 rotated_dest_size =
415 gfx::SizeF(rotated_dest_size.height(), rotated_dest_size.width()); 305 gfx::SizeF(rotated_dest_size.height(), rotated_dest_size.width());
416 } 306 }
417 canvas->scale( 307 canvas->scale(
418 SkFloatToScalar(rotated_dest_size.width() / target_frame->width()), 308 SkFloatToScalar(rotated_dest_size.width() / target_frame->width()),
419 SkFloatToScalar(rotated_dest_size.height() / target_frame->height())); 309 SkFloatToScalar(rotated_dest_size.height() / target_frame->height()));
420 canvas->translate(-SkFloatToScalar(target_frame->width() * 0.5f), 310 canvas->translate(-SkFloatToScalar(target_frame->width() * 0.5f),
421 -SkFloatToScalar(target_frame->height() * 0.5f)); 311 -SkFloatToScalar(target_frame->height() * 0.5f));
422 } 312 }
423 canvas->drawBitmap(*target_frame, 0, 0, &paint); 313 canvas->drawImage(target_frame.get(), 0, 0, &paint);
424 if (need_transform) 314 if (need_transform)
425 canvas->restore(); 315 canvas->restore();
426 canvas->flush(); 316 canvas->flush();
427 // SkCanvas::flush() causes the generator to generate SkImage, so delete 317 target_frame.clear();
428 // |video_frame| not to be outlived. 318 // When target_frame is created from a backend texture, calling
429 if (canvas->getGrContext() && accelerated_generator_) 319 // textureSkCanvas::flush() causes Skia to use all the resources backing the
430 accelerated_generator_->set_frame(nullptr); 320 // SkImage and the underlying texture can be delete.
321 // TODO(dcastagna): release the texture in a callback once Skia API exposes
bsalomon 2015/05/29 14:49:26 Why don't we go ahead and add this functionality t
Daniele Castagna 2015/06/05 04:15:31 With the last patch texture_id is kept around for
322 // the functionality.
323 if (texture_id) {
324 DCHECK(!IsCanvasDrawingOnPicture(canvas));
325 DCHECK(context_3d.gl);
326 context_3d.gl->DeleteTextures(1, &texture_id);
327 }
431 } 328 }
432 329
433 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, 330 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
434 SkCanvas* canvas, 331 SkCanvas* canvas,
435 const Context3D& context_3d) { 332 const Context3D& context_3d) {
436 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff, 333 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff,
437 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, context_3d); 334 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, context_3d);
438 } 335 }
439 336
440 // static 337 // static
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 gl->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, false); 504 gl->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, false);
608 gl->PixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false); 505 gl->PixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false);
609 506
610 gl->DeleteTextures(1, &source_texture); 507 gl->DeleteTextures(1, &source_texture);
611 gl->Flush(); 508 gl->Flush();
612 509
613 SyncPointClientImpl client(gl); 510 SyncPointClientImpl client(gl);
614 video_frame->UpdateReleaseSyncPoint(&client); 511 video_frame->UpdateReleaseSyncPoint(&client);
615 } 512 }
616 513
617 void SkCanvasVideoRenderer::ResetLastFrame() {
618 last_frame_.reset();
619 last_frame_timestamp_ = media::kNoTimestamp();
620 }
621
622 void SkCanvasVideoRenderer::ResetAcceleratedLastFrame() {
623 accelerated_last_frame_.reset();
624 accelerated_generator_ = nullptr;
625 accelerated_last_frame_timestamp_ = media::kNoTimestamp();
626 }
627
628 } // namespace media 514 } // namespace media
OLDNEW
« no previous file with comments | « media/blink/skcanvas_video_renderer.h ('k') | media/blink/skcanvas_video_renderer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698