image_transport_factory_android.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// Use of this source code is governed by a BSD-style license that can be 3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// found in the LICENSE file. 4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "content/browser/renderer_host/image_transport_factory_android.h" 6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "base/lazy_instance.h" 8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "base/strings/stringprintf.h" 9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "content/browser/gpu/browser_gpu_channel_host_factory.h" 10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "content/common/gpu/client/gl_helper.h" 11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "content/common/gpu/gpu_process_launch_causes.h" 13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "gpu/command_buffer/client/gles2_implementation.h" 14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "third_party/khronos/GLES2/gl2.h" 16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "ui/gfx/android/device_display_info.h" 17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogennamespace content { 19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenbase::LazyInstance<ObserverList<ImageTransportFactoryAndroidObserver> >::Leaky 21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen g_factory_observers = LAZY_INSTANCE_INITIALIZER; 22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass GLContextLostListener 24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback { 25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public: 26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // WebGraphicsContextLostCallback implementation. 27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual void onContextLost() OVERRIDE; 28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private: 29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen static void DidLoseContext(); 30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen}; 31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogennamespace { 33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenstatic ImageTransportFactoryAndroid* g_factory = NULL; 35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass CmdBufferImageTransportFactory : public ImageTransportFactoryAndroid { 37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public: 38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen CmdBufferImageTransportFactory(); 39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual ~CmdBufferImageTransportFactory(); 40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual uint32_t InsertSyncPoint() OVERRIDE; 42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual void WaitSyncPoint(uint32_t sync_point) OVERRIDE; 43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual uint32_t CreateTexture() OVERRIDE; 44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual void DeleteTexture(uint32_t id) OVERRIDE; 45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual void AcquireTexture( 46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen uint32 texture_id, const signed char* mailbox_name) OVERRIDE; 47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual gpu::gles2::GLES2Interface* GetContextGL() OVERRIDE { 48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return context_->GetImplementation(); 49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual GLHelper* GetGLHelper() OVERRIDE; 51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen virtual uint32 GetChannelID() OVERRIDE { 52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return BrowserGpuChannelHostFactory::instance()->GetGpuChannelId(); 53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private: 56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context_; 57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen scoped_ptr<GLHelper> gl_helper_; 58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen DISALLOW_COPY_AND_ASSIGN(CmdBufferImageTransportFactory); 60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen}; 61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 62674060f01e9090cd21b3c5656cc3204912ad17a6Jon BoekenoogenCmdBufferImageTransportFactory::CmdBufferImageTransportFactory() { 63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen BrowserGpuChannelHostFactory* factory = 64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen BrowserGpuChannelHostFactory::instance(); 65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen scoped_refptr<GpuChannelHost> gpu_channel_host(factory->EstablishGpuChannelSync( 66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)); 67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen DCHECK(gpu_channel_host); 68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen blink::WebGraphicsContext3D::Attributes attrs; 70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen attrs.shareResources = true; 71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen GURL url("chrome://gpu/ImageTransportFactoryAndroid"); 72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen static const size_t kBytesPerPixel = 4; 73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen gfx::DeviceDisplayInfo display_info; 74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen size_t full_screen_texture_size_in_bytes = display_info.GetDisplayHeight() * 75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen display_info.GetDisplayWidth() * 76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen kBytesPerPixel; 77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits; 78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen limits.command_buffer_size = 64 * 1024; 79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen limits.start_transfer_buffer_size = 64 * 1024; 80 limits.min_transfer_buffer_size = 64 * 1024; 81 limits.max_transfer_buffer_size = std::min( 82 3 * full_screen_texture_size_in_bytes, kDefaultMaxTransferBufferSize); 83 limits.mapped_memory_reclaim_limit = 84 WebGraphicsContext3DCommandBufferImpl::kNoLimit; 85 context_.reset( 86 new WebGraphicsContext3DCommandBufferImpl(0, // offscreen 87 url, 88 gpu_channel_host.get(), 89 attrs, 90 false, 91 limits)); 92 context_->setContextLostCallback(context_lost_listener_.get()); 93 if (context_->makeContextCurrent()) 94 context_->pushGroupMarkerEXT( 95 base::StringPrintf("CmdBufferImageTransportFactory-%p", 96 context_.get()).c_str()); 97} 98 99CmdBufferImageTransportFactory::~CmdBufferImageTransportFactory() { 100 context_->setContextLostCallback(NULL); 101} 102 103uint32_t CmdBufferImageTransportFactory::InsertSyncPoint() { 104 if (!context_->makeContextCurrent()) { 105 LOG(ERROR) << "Failed to make helper context current."; 106 return 0; 107 } 108 return context_->insertSyncPoint(); 109} 110 111void CmdBufferImageTransportFactory::WaitSyncPoint(uint32_t sync_point) { 112 if (!context_->makeContextCurrent()) { 113 LOG(ERROR) << "Failed to make helper context current."; 114 return; 115 } 116 context_->waitSyncPoint(sync_point); 117} 118 119uint32_t CmdBufferImageTransportFactory::CreateTexture() { 120 if (!context_->makeContextCurrent()) { 121 LOG(ERROR) << "Failed to make helper context current."; 122 return false; 123 } 124 return context_->createTexture(); 125} 126 127void CmdBufferImageTransportFactory::DeleteTexture(uint32_t id) { 128 if (!context_->makeContextCurrent()) { 129 LOG(ERROR) << "Failed to make helper context current."; 130 return; 131 } 132 context_->deleteTexture(id); 133} 134 135void CmdBufferImageTransportFactory::AcquireTexture( 136 uint32 texture_id, const signed char* mailbox_name) { 137 if (!context_->makeContextCurrent()) { 138 LOG(ERROR) << "Failed to make helper context current."; 139 return; 140 } 141 context_->bindTexture(GL_TEXTURE_2D, texture_id); 142 context_->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox_name); 143 context_->shallowFlushCHROMIUM(); 144} 145 146GLHelper* CmdBufferImageTransportFactory::GetGLHelper() { 147 if (!gl_helper_) 148 gl_helper_.reset(new GLHelper(context_->GetImplementation(), 149 context_->GetContextSupport())); 150 151 return gl_helper_.get(); 152} 153 154} // anonymous namespace 155 156// static 157ImageTransportFactoryAndroid* ImageTransportFactoryAndroid::GetInstance() { 158 if (!g_factory) 159 g_factory = new CmdBufferImageTransportFactory(); 160 161 return g_factory; 162} 163 164ImageTransportFactoryAndroid::ImageTransportFactoryAndroid() 165 : context_lost_listener_(new GLContextLostListener()) {} 166 167ImageTransportFactoryAndroid::~ImageTransportFactoryAndroid() {} 168 169void ImageTransportFactoryAndroid::AddObserver( 170 ImageTransportFactoryAndroidObserver* observer) { 171 g_factory_observers.Get().AddObserver(observer); 172} 173 174void ImageTransportFactoryAndroid::RemoveObserver( 175 ImageTransportFactoryAndroidObserver* observer) { 176 g_factory_observers.Get().RemoveObserver(observer); 177} 178 179void GLContextLostListener::onContextLost() { 180 // Need to post a task because the command buffer client cannot be deleted 181 // from within this callback. 182 LOG(ERROR) << "Context lost."; 183 base::MessageLoop::current()->PostTask( 184 FROM_HERE, 185 base::Bind(&GLContextLostListener::DidLoseContext)); 186} 187 188void GLContextLostListener::DidLoseContext() { 189 delete g_factory; 190 g_factory = NULL; 191 FOR_EACH_OBSERVER(ImageTransportFactoryAndroidObserver, 192 g_factory_observers.Get(), 193 OnLostResources()); 194} 195 196} // namespace content 197