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

Side by Side Diff: media/gpu/dxva_picture_buffer_win.cc

Issue 2495753002: Reenable idle suspension of media elements on Windows. (Closed)
Patch Set: add comment Created 4 years, 1 month 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/gpu/dxva_picture_buffer_win.h ('k') | media/gpu/dxva_video_decode_accelerator_win.h » ('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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/gpu/dxva_picture_buffer_win.h" 5 #include "media/gpu/dxva_picture_buffer_win.h"
6 6
7 #include "media/gpu/dxva_video_decode_accelerator_win.h" 7 #include "media/gpu/dxva_video_decode_accelerator_win.h"
8 #include "third_party/angle/include/EGL/egl.h" 8 #include "third_party/angle/include/EGL/egl.h"
9 #include "third_party/angle/include/EGL/eglext.h" 9 #include "third_party/angle/include/EGL/eglext.h"
10 #include "ui/gl/gl_bindings.h" 10 #include "ui/gl/gl_bindings.h"
11 #include "ui/gl/gl_context.h" 11 #include "ui/gl/gl_context.h"
12 #include "ui/gl/gl_fence.h" 12 #include "ui/gl/gl_fence.h"
13 #include "ui/gl/gl_image.h"
13 #include "ui/gl/gl_surface_egl.h" 14 #include "ui/gl/gl_surface_egl.h"
14 #include "ui/gl/scoped_binders.h" 15 #include "ui/gl/scoped_binders.h"
15 16
16 namespace media { 17 namespace media {
17 18
18 namespace { 19 namespace {
19 20
20 void LogDXVAError(int line) { 21 void LogDXVAError(int line) {
21 LOG(ERROR) << "Error in dxva_picture_buffer_win.cc on line " << line; 22 LOG(ERROR) << "Error in dxva_picture_buffer_win.cc on line " << line;
22 } 23 }
23 24
25 // These GLImage subclasses are just used to hold references to the underlying
26 // image content so it can be destroyed when the textures are.
27 class DummyGLImage : public gl::GLImage {
28 public:
29 DummyGLImage(const gfx::Size& size) : size_(size) {}
30
31 // gl::GLImage implementation.
32 gfx::Size GetSize() override { return size_; }
33 unsigned GetInternalFormat() override { return GL_BGRA_EXT; }
34 bool BindTexImage(unsigned target) override { return false; }
35 void ReleaseTexImage(unsigned target) override {}
36 bool CopyTexImage(unsigned target) override { return false; }
37 bool CopyTexSubImage(unsigned target,
38 const gfx::Point& offset,
39 const gfx::Rect& rect) override {
40 return false;
41 }
42 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
43 int z_order,
44 gfx::OverlayTransform transform,
45 const gfx::Rect& bounds_rect,
46 const gfx::RectF& crop_rect) override {
47 return false;
48 }
49 void Flush() override {}
50 void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
51 uint64_t process_tracing_id,
52 const std::string& dump_name) override {}
53
54 protected:
55 ~DummyGLImage() override {}
56
57 private:
58 gfx::Size size_;
59 };
60
61 class GLImagePbuffer : public DummyGLImage {
62 public:
63 GLImagePbuffer(const gfx::Size& size, EGLSurface surface)
64 : DummyGLImage(size), surface_(surface) {}
65
66 private:
67 ~GLImagePbuffer() override {
68 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
69
70 eglReleaseTexImage(egl_display, surface_, EGL_BACK_BUFFER);
71
72 eglDestroySurface(egl_display, surface_);
73 }
74
75 EGLSurface surface_;
76 };
77
78 class GLImageEGLStream : public DummyGLImage {
79 public:
80 GLImageEGLStream(const gfx::Size& size, EGLStreamKHR stream)
81 : DummyGLImage(size), stream_(stream) {}
82
83 private:
84 ~GLImageEGLStream() override {
85 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
86 eglDestroyStreamKHR(egl_display, stream_);
87 }
88
89 EGLStreamKHR stream_;
90 };
91
24 } // namespace 92 } // namespace
25 93
26 #define RETURN_ON_FAILURE(result, log, ret) \ 94 #define RETURN_ON_FAILURE(result, log, ret) \
27 do { \ 95 do { \
28 if (!(result)) { \ 96 if (!(result)) { \
29 DLOG(ERROR) << log; \ 97 DLOG(ERROR) << log; \
30 LogDXVAError(__LINE__); \ 98 LogDXVAError(__LINE__); \
31 return ret; \ 99 return ret; \
32 } \ 100 } \
33 } while (0) 101 } while (0)
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 EGL_TEXTURE_FORMAT, 199 EGL_TEXTURE_FORMAT,
132 use_rgb ? EGL_TEXTURE_RGB : EGL_TEXTURE_RGBA, 200 use_rgb ? EGL_TEXTURE_RGB : EGL_TEXTURE_RGBA,
133 EGL_TEXTURE_TARGET, 201 EGL_TEXTURE_TARGET,
134 EGL_TEXTURE_2D, 202 EGL_TEXTURE_2D,
135 EGL_NONE}; 203 EGL_NONE};
136 204
137 decoding_surface_ = eglCreatePbufferFromClientBuffer( 205 decoding_surface_ = eglCreatePbufferFromClientBuffer(
138 egl_display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, texture_share_handle_, 206 egl_display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, texture_share_handle_,
139 egl_config, attrib_list); 207 egl_config, attrib_list);
140 RETURN_ON_FAILURE(decoding_surface_, "Failed to create surface", false); 208 RETURN_ON_FAILURE(decoding_surface_, "Failed to create surface", false);
209 gl_image_ = make_scoped_refptr(new GLImagePbuffer(size(), decoding_surface_));
141 if (decoder.d3d11_device_ && decoder.use_keyed_mutex_) { 210 if (decoder.d3d11_device_ && decoder.use_keyed_mutex_) {
142 void* keyed_mutex = nullptr; 211 void* keyed_mutex = nullptr;
143 EGLBoolean ret = 212 EGLBoolean ret =
144 eglQuerySurfacePointerANGLE(egl_display, decoding_surface_, 213 eglQuerySurfacePointerANGLE(egl_display, decoding_surface_,
145 EGL_DXGI_KEYED_MUTEX_ANGLE, &keyed_mutex); 214 EGL_DXGI_KEYED_MUTEX_ANGLE, &keyed_mutex);
146 RETURN_ON_FAILURE(keyed_mutex && ret == EGL_TRUE, 215 RETURN_ON_FAILURE(keyed_mutex && ret == EGL_TRUE,
147 "Failed to query ANGLE keyed mutex", false); 216 "Failed to query ANGLE keyed mutex", false);
148 egl_keyed_mutex_ = base::win::ScopedComPtr<IDXGIKeyedMutex>( 217 egl_keyed_mutex_ = base::win::ScopedComPtr<IDXGIKeyedMutex>(
149 static_cast<IDXGIKeyedMutex*>(keyed_mutex)); 218 static_cast<IDXGIKeyedMutex*>(keyed_mutex));
150 } 219 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 } 375 }
307 376
308 PbufferPictureBuffer::PbufferPictureBuffer(const PictureBuffer& buffer) 377 PbufferPictureBuffer::PbufferPictureBuffer(const PictureBuffer& buffer)
309 : DXVAPictureBuffer(buffer), 378 : DXVAPictureBuffer(buffer),
310 decoding_surface_(NULL), 379 decoding_surface_(NULL),
311 texture_share_handle_(nullptr), 380 texture_share_handle_(nullptr),
312 keyed_mutex_value_(0), 381 keyed_mutex_value_(0),
313 use_rgb_(true) {} 382 use_rgb_(true) {}
314 383
315 PbufferPictureBuffer::~PbufferPictureBuffer() { 384 PbufferPictureBuffer::~PbufferPictureBuffer() {
316 if (decoding_surface_) { 385 // decoding_surface_ will be deleted by gl_image_.
317 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
318
319 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER);
320
321 eglDestroySurface(egl_display, decoding_surface_);
322 decoding_surface_ = NULL;
323 }
324 } 386 }
325 387
326 bool PbufferPictureBuffer::ReusePictureBuffer() { 388 bool PbufferPictureBuffer::ReusePictureBuffer() {
327 DCHECK_NE(UNUSED, state_); 389 DCHECK_NE(UNUSED, state_);
328 DCHECK(decoding_surface_); 390 DCHECK(decoding_surface_);
329 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); 391 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
330 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); 392 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER);
331 393
332 decoder_surface_.Release(); 394 decoder_surface_.Release();
333 target_surface_.Release(); 395 target_surface_.Release();
334 decoder_dx11_texture_.Release(); 396 decoder_dx11_texture_.Release();
335 state_ = UNUSED; 397 state_ = UNUSED;
336 if (egl_keyed_mutex_) { 398 if (egl_keyed_mutex_) {
337 HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_); 399 HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_);
338 RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false); 400 RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false);
339 } 401 }
340 return true; 402 return true;
341 } 403 }
342 404
343 EGLStreamPictureBuffer::EGLStreamPictureBuffer(const PictureBuffer& buffer) 405 EGLStreamPictureBuffer::EGLStreamPictureBuffer(const PictureBuffer& buffer)
344 : DXVAPictureBuffer(buffer), stream_(nullptr) {} 406 : DXVAPictureBuffer(buffer), stream_(nullptr) {}
345 407
346 EGLStreamPictureBuffer::~EGLStreamPictureBuffer() { 408 EGLStreamPictureBuffer::~EGLStreamPictureBuffer() {
347 if (stream_) { 409 // stream_ will be deleted by gl_image_.
348 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
349 eglDestroyStreamKHR(egl_display, stream_);
350 stream_ = nullptr;
351 }
352 } 410 }
353 411
354 bool EGLStreamPictureBuffer::Initialize() { 412 bool EGLStreamPictureBuffer::Initialize() {
355 RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2, 413 RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2,
356 "Not enough texture ids provided", false); 414 "Not enough texture ids provided", false);
357 415
358 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); 416 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
359 const EGLint stream_attributes[] = { 417 const EGLint stream_attributes[] = {
360 EGL_CONSUMER_LATENCY_USEC_KHR, 418 EGL_CONSUMER_LATENCY_USEC_KHR,
361 0, 419 0,
362 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 420 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR,
363 0, 421 0,
364 EGL_NONE, 422 EGL_NONE,
365 }; 423 };
366 stream_ = eglCreateStreamKHR(egl_display, stream_attributes); 424 stream_ = eglCreateStreamKHR(egl_display, stream_attributes);
367 RETURN_ON_FAILURE(!!stream_, "Could not create stream", false); 425 RETURN_ON_FAILURE(!!stream_, "Could not create stream", false);
426 gl_image_ = make_scoped_refptr(new GLImageEGLStream(size(), stream_));
368 gl::ScopedActiveTexture texture0(GL_TEXTURE0); 427 gl::ScopedActiveTexture texture0(GL_TEXTURE0);
369 gl::ScopedTextureBinder texture0_binder( 428 gl::ScopedTextureBinder texture0_binder(
370 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[0]); 429 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[0]);
371 gl::ScopedActiveTexture texture1(GL_TEXTURE1); 430 gl::ScopedActiveTexture texture1(GL_TEXTURE1);
372 gl::ScopedTextureBinder texture1_binder( 431 gl::ScopedTextureBinder texture1_binder(
373 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[1]); 432 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[1]);
374 433
375 EGLAttrib consumer_attributes[] = { 434 EGLAttrib consumer_attributes[] = {
376 EGL_COLOR_BUFFER_TYPE, 435 EGL_COLOR_BUFFER_TYPE,
377 EGL_YUV_BUFFER_EXT, 436 EGL_YUV_BUFFER_EXT,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 result = eglStreamConsumerAcquireKHR(egl_display, stream_); 505 result = eglStreamConsumerAcquireKHR(egl_display, stream_);
447 RETURN_ON_FAILURE(result, "Could not post acquire stream", false); 506 RETURN_ON_FAILURE(result, "Could not post acquire stream", false);
448 return true; 507 return true;
449 } 508 }
450 509
451 EGLStreamCopyPictureBuffer::EGLStreamCopyPictureBuffer( 510 EGLStreamCopyPictureBuffer::EGLStreamCopyPictureBuffer(
452 const PictureBuffer& buffer) 511 const PictureBuffer& buffer)
453 : DXVAPictureBuffer(buffer), stream_(nullptr) {} 512 : DXVAPictureBuffer(buffer), stream_(nullptr) {}
454 513
455 EGLStreamCopyPictureBuffer::~EGLStreamCopyPictureBuffer() { 514 EGLStreamCopyPictureBuffer::~EGLStreamCopyPictureBuffer() {
456 if (stream_) { 515 // stream_ will be deleted by gl_image_.
457 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
458 eglDestroyStreamKHR(egl_display, stream_);
459 stream_ = nullptr;
460 }
461 } 516 }
462 517
463 bool EGLStreamCopyPictureBuffer::Initialize( 518 bool EGLStreamCopyPictureBuffer::Initialize(
464 const DXVAVideoDecodeAccelerator& decoder) { 519 const DXVAVideoDecodeAccelerator& decoder) {
465 RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2, 520 RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2,
466 "Not enough texture ids provided", false); 521 "Not enough texture ids provided", false);
467 522
468 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); 523 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
469 const EGLint stream_attributes[] = { 524 const EGLint stream_attributes[] = {
470 EGL_CONSUMER_LATENCY_USEC_KHR, 525 EGL_CONSUMER_LATENCY_USEC_KHR,
471 0, 526 0,
472 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 527 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR,
473 0, 528 0,
474 EGL_NONE, 529 EGL_NONE,
475 }; 530 };
476 stream_ = eglCreateStreamKHR(egl_display, stream_attributes); 531 stream_ = eglCreateStreamKHR(egl_display, stream_attributes);
477 RETURN_ON_FAILURE(!!stream_, "Could not create stream", false); 532 RETURN_ON_FAILURE(!!stream_, "Could not create stream", false);
533 gl_image_ = make_scoped_refptr(new GLImageEGLStream(size(), stream_));
478 gl::ScopedActiveTexture texture0(GL_TEXTURE0); 534 gl::ScopedActiveTexture texture0(GL_TEXTURE0);
479 gl::ScopedTextureBinder texture0_binder( 535 gl::ScopedTextureBinder texture0_binder(
480 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[0]); 536 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[0]);
481 gl::ScopedActiveTexture texture1(GL_TEXTURE1); 537 gl::ScopedActiveTexture texture1(GL_TEXTURE1);
482 gl::ScopedTextureBinder texture1_binder( 538 gl::ScopedTextureBinder texture1_binder(
483 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[1]); 539 GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[1]);
484 540
485 EGLAttrib consumer_attributes[] = { 541 EGLAttrib consumer_attributes[] = {
486 EGL_COLOR_BUFFER_TYPE, 542 EGL_COLOR_BUFFER_TYPE,
487 EGL_YUV_BUFFER_EXT, 543 EGL_YUV_BUFFER_EXT,
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 state_ = UNUSED; 659 state_ = UNUSED;
604 660
605 if (stream_) { 661 if (stream_) {
606 EGLBoolean result = eglStreamConsumerReleaseKHR(egl_display, stream_); 662 EGLBoolean result = eglStreamConsumerReleaseKHR(egl_display, stream_);
607 RETURN_ON_FAILURE(result, "Could not release stream", false); 663 RETURN_ON_FAILURE(result, "Could not release stream", false);
608 } 664 }
609 return true; 665 return true;
610 } 666 }
611 667
612 } // namespace media 668 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/dxva_picture_buffer_win.h ('k') | media/gpu/dxva_video_decode_accelerator_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698