15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2ext.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_thread.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/client/gpu_channel_host.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/ipc/command_buffer_proxy.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/skia/include/core/SkPixelRef.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories( 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelHost* gpu_channel_host, 23bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const scoped_refptr<base::MessageLoopProxy>& message_loop, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebGraphicsContext3DCommandBufferImpl* context) 25bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch : message_loop_(message_loop), 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch main_message_loop_(base::MessageLoopProxy::current()), 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gpu_channel_host_(gpu_channel_host), 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aborted_waiter_(true, false), 29bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_(false, false), 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_thread_async_waiter_(false, false) { 31bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (message_loop_->BelongsToCurrentThread()) { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AsyncGetContext(context); 33bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Reset(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Wait for the context to be acquired. 37bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_->PostTask(FROM_HERE, base::Bind( 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &RendererGpuVideoDecoderFactories::AsyncGetContext, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scoped_refptr. Safe because the Wait() below keeps us alive until this 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // task completes. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK to pass raw because the pointee is only deleted on the compositor 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread, and only as the result of a PostTask from the render thread 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which can only happen after this function returns, so our PostTask will 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // run first. 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) context)); 48bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Wait(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochRendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories() 52bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch : aborted_waiter_(true, false), 53bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_(false, false), 54bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch render_thread_async_waiter_(false, false) {} 55bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererGpuVideoDecoderFactories::AsyncGetContext( 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebGraphicsContext3DCommandBufferImpl* context) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_ = context->AsWeakPtr(); 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (context_.get()) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_->makeContextCurrent()) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called once per media player, but is a no-op after the first one in 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // each renderer. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->insertEventMarkerEXT("GpuVDAContext3D"); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)media::VideoDecodeAccelerator* 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoCodecProfile profile, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoDecodeAccelerator::Client* client) { 73bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (message_loop_->BelongsToCurrentThread()) { 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AsyncCreateVideoDecodeAccelerator(profile, client); 75bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Reset(); 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return vda_.release(); 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The VDA is returned in the vda_ member variable by the 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // AsyncCreateVideoDecodeAccelerator() function. 80bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_->PostTask(FROM_HERE, base::Bind( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, profile, client)); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent* objects[] = {&aborted_waiter_, 85bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch &message_loop_async_waiter_}; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If we are aborting and the VDA is created by the 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // AsyncCreateVideoDecodeAccelerator() function later we need to ensure 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that it is destroyed on the same thread. 90bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_->PostTask(FROM_HERE, base::Bind( 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this)); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return vda_.release(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoCodecProfile profile, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media::VideoDecodeAccelerator::Client* client) { 101bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(message_loop_->BelongsToCurrentThread()); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (context_.get() && context_->GetCommandBufferProxy()) { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) vda_ = gpu_channel_host_->CreateVideoDecoder( 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) context_->GetCommandBufferProxy()->GetRouteID(), profile, client); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 107bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochuint32 RendererGpuVideoDecoderFactories::CreateTextures( 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 count, const gfx::Size& size, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint32>* texture_ids, 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<gpu::Mailbox>* texture_mailboxes, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 texture_target) { 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 sync_point = 0; 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (message_loop_->BelongsToCurrentThread()) { 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AsyncCreateTextures(count, size, texture_target, &sync_point); 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch texture_ids->swap(created_textures_); 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch texture_mailboxes->swap(created_texture_mailboxes_); 121bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Reset(); 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return sync_point; 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 124bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_->PostTask(FROM_HERE, base::Bind( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch count, size, texture_target, &sync_point)); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent* objects[] = {&aborted_waiter_, 129bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch &message_loop_async_waiter_}; 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) texture_ids->swap(created_textures_); 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch texture_mailboxes->swap(created_texture_mailboxes_); 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return sync_point; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererGpuVideoDecoderFactories::AsyncCreateTextures( 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int32 count, const gfx::Size& size, uint32 texture_target, 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32* sync_point) { 140bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(message_loop_->BelongsToCurrentThread()); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(texture_target); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context_.get()) { 144bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) created_textures_.resize(count); 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch created_texture_mailboxes_.resize(count); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gles2->GenTextures(count, &created_textures_[0]); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < count; ++i) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->ActiveTexture(GL_TEXTURE0); 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 texture_id = created_textures_[i]; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->BindTexture(texture_target, texture_id); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (texture_target == GL_TEXTURE_2D) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name); 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gles2->ProduceTextureCHROMIUM(texture_target, 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch created_texture_mailboxes_[i].name); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need a glFlush here to guarantee the decoder (in the GPU process) can 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use the texture ids we return here. Since textures are expected to be 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reused, this should not be unacceptably expensive. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->Flush(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *sync_point = gles2->InsertSyncPointCHROMIUM(); 175bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { 179bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (message_loop_->BelongsToCurrentThread()) { 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AsyncDeleteTexture(texture_id); 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 183bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_->PostTask(FROM_HERE, base::Bind( 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { 188bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(message_loop_->BelongsToCurrentThread()); 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context_.get()) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->DeleteTextures(1, &texture_id); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RendererGpuVideoDecoderFactories::WaitSyncPoint(uint32 sync_point) { 198bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (message_loop_->BelongsToCurrentThread()) { 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AsyncWaitSyncPoint(sync_point); 200bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Reset(); 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 204bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_->PostTask(FROM_HERE, base::Bind( 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint, 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch this, 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sync_point)); 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WaitableEvent* objects[] = {&aborted_waiter_, 209bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch &message_loop_async_waiter_}; 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WaitableEvent::WaitMany(objects, arraysize(objects)); 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) { 214bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(message_loop_->BelongsToCurrentThread()); 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!context_) { 216bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gles2->WaitSyncPointCHROMIUM(sync_point); 222bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererGpuVideoDecoderFactories::ReadPixels( 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 texture_id, uint32 texture_target, const gfx::Size& size, 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SkBitmap& pixels) { 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Multiple SkBitmaps can share a SkPixelRef instance. We use this to 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ensure that the underlying pixels in the SkBitmap passed in remain valid 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // until the AsyncReadPixels() call completes. 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!message_loop_->BelongsToCurrentThread()) { 235bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_->PostTask(FROM_HERE, base::Bind( 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &RendererGpuVideoDecoderFactories::AsyncReadPixels, this, 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) texture_id, texture_target, size)); 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent* objects[] = {&aborted_waiter_, 239bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch &message_loop_async_waiter_}; 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AsyncReadPixels(texture_id, texture_target, size); 244bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Reset(); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) read_pixels_bitmap_.setPixelRef(NULL); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererGpuVideoDecoderFactories::AsyncReadPixels( 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 texture_id, uint32 texture_target, const gfx::Size& size) { 251bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(message_loop_->BelongsToCurrentThread()); 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context_.get()) { 253bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint tmp_texture; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->GenTextures(1, &tmp_texture); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->BindTexture(texture_target, tmp_texture); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->copyTextureCHROMIUM( 267a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) texture_target, texture_id, tmp_texture, 0, GL_RGBA, GL_UNSIGNED_BYTE); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint fb; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->GenFramebuffers(1, &fb); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->BindFramebuffer(GL_FRAMEBUFFER, fb); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_target, tmp_texture, 0); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->PixelStorei(GL_PACK_ALIGNMENT, 4); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->DeleteFramebuffers(1, &fb); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2->DeleteTextures(1, &tmp_texture); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 280bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_async_waiter_.Signal(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size) { 2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (main_message_loop_->BelongsToCurrentThread()) { 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return ChildThread::current()->AllocateSharedMemory(size); 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch main_message_loop_->PostTask(FROM_HERE, base::Bind( 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size)); 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WaitableEvent* objects[] = {&aborted_waiter_, 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &render_thread_async_waiter_}; 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return shared_memory_segment_.release(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) { 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ChildThread::current()->message_loop()); 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_memory_segment_.reset( 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ChildThread::current()->AllocateSharedMemory(size)); 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_thread_async_waiter_.Signal(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::MessageLoopProxy> 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)RendererGpuVideoDecoderFactories::GetMessageLoop() { 310bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return message_loop_; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RendererGpuVideoDecoderFactories::Abort() { 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aborted_waiter_.Signal(); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool RendererGpuVideoDecoderFactories::IsAborted() { 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return aborted_waiter_.IsSignaled(); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 321bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochscoped_refptr<media::GpuVideoDecoderFactories> 322bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochRendererGpuVideoDecoderFactories::Clone() { 323bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_refptr<RendererGpuVideoDecoderFactories> factories = 324bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch new RendererGpuVideoDecoderFactories(); 325bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch factories->message_loop_ = message_loop_; 326bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch factories->main_message_loop_ = main_message_loop_; 327bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch factories->gpu_channel_host_ = gpu_channel_host_; 328bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch factories->context_ = context_; 329bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return factories; 330bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 331bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // OK to release because Destroy() will delete the VDA instance. 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (vda_) 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) vda_.release()->Destroy(); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 339