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
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/image_transport_factory_android.h"
7 #include "base/lazy_instance.h"
8 #include "base/strings/stringprintf.h"
9 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
10 #include "content/common/gpu/client/gl_helper.h"
11 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
12 #include "content/common/gpu/gpu_process_launch_causes.h"
13 #include "gpu/command_buffer/client/gles2_implementation.h"
14 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
15 #include "third_party/khronos/GLES2/gl2.h"
16 #include "ui/gfx/android/device_display_info.h"
20 base::LazyInstance
<ObserverList
<ImageTransportFactoryAndroidObserver
> >::Leaky
21 g_factory_observers
= LAZY_INSTANCE_INITIALIZER
;
23 class GLContextLostListener
24 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback
{
26 // WebGraphicsContextLostCallback implementation.
27 virtual void onContextLost() OVERRIDE
;
29 static void DidLoseContext();
34 static ImageTransportFactoryAndroid
* g_factory
= NULL
;
36 class CmdBufferImageTransportFactory
: public ImageTransportFactoryAndroid
{
38 CmdBufferImageTransportFactory();
39 virtual ~CmdBufferImageTransportFactory();
41 virtual uint32_t InsertSyncPoint() OVERRIDE
;
42 virtual void WaitSyncPoint(uint32_t sync_point
) OVERRIDE
;
43 virtual uint32_t CreateTexture() OVERRIDE
;
44 virtual void DeleteTexture(uint32_t id
) OVERRIDE
;
45 virtual void AcquireTexture(
46 uint32 texture_id
, const signed char* mailbox_name
) OVERRIDE
;
47 virtual gpu::gles2::GLES2Interface
* GetContextGL() OVERRIDE
{
48 return context_
->GetImplementation();
50 virtual GLHelper
* GetGLHelper() OVERRIDE
;
51 virtual uint32
GetChannelID() OVERRIDE
{
52 return BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
56 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context_
;
57 scoped_ptr
<GLHelper
> gl_helper_
;
59 DISALLOW_COPY_AND_ASSIGN(CmdBufferImageTransportFactory
);
62 CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() {
63 BrowserGpuChannelHostFactory
* factory
=
64 BrowserGpuChannelHostFactory::instance();
65 scoped_refptr
<GpuChannelHost
> gpu_channel_host(factory
->EstablishGpuChannelSync(
66 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
));
67 DCHECK(gpu_channel_host
);
69 blink::WebGraphicsContext3D::Attributes attrs
;
70 attrs
.shareResources
= true;
71 GURL
url("chrome://gpu/ImageTransportFactoryAndroid");
72 static const size_t kBytesPerPixel
= 4;
73 gfx::DeviceDisplayInfo display_info
;
74 size_t full_screen_texture_size_in_bytes
= display_info
.GetDisplayHeight() *
75 display_info
.GetDisplayWidth() *
77 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits
;
78 limits
.command_buffer_size
= 64 * 1024;
79 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
;
86 new WebGraphicsContext3DCommandBufferImpl(0, // offscreen
88 gpu_channel_host
.get(),
93 context_
->setContextLostCallback(context_lost_listener_
.get());
94 if (context_
->makeContextCurrent())
95 context_
->pushGroupMarkerEXT(
96 base::StringPrintf("CmdBufferImageTransportFactory-%p",
97 context_
.get()).c_str());
100 CmdBufferImageTransportFactory::~CmdBufferImageTransportFactory() {
101 context_
->setContextLostCallback(NULL
);
104 uint32_t CmdBufferImageTransportFactory::InsertSyncPoint() {
105 if (!context_
->makeContextCurrent()) {
106 LOG(ERROR
) << "Failed to make helper context current.";
109 return context_
->insertSyncPoint();
112 void CmdBufferImageTransportFactory::WaitSyncPoint(uint32_t sync_point
) {
113 if (!context_
->makeContextCurrent()) {
114 LOG(ERROR
) << "Failed to make helper context current.";
117 context_
->waitSyncPoint(sync_point
);
120 uint32_t CmdBufferImageTransportFactory::CreateTexture() {
121 if (!context_
->makeContextCurrent()) {
122 LOG(ERROR
) << "Failed to make helper context current.";
125 return context_
->createTexture();
128 void CmdBufferImageTransportFactory::DeleteTexture(uint32_t id
) {
129 if (!context_
->makeContextCurrent()) {
130 LOG(ERROR
) << "Failed to make helper context current.";
133 context_
->deleteTexture(id
);
136 void CmdBufferImageTransportFactory::AcquireTexture(
137 uint32 texture_id
, const signed char* mailbox_name
) {
138 if (!context_
->makeContextCurrent()) {
139 LOG(ERROR
) << "Failed to make helper context current.";
142 context_
->bindTexture(GL_TEXTURE_2D
, texture_id
);
143 context_
->consumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox_name
);
144 context_
->shallowFlushCHROMIUM();
147 GLHelper
* CmdBufferImageTransportFactory::GetGLHelper() {
149 gl_helper_
.reset(new GLHelper(context_
->GetImplementation(),
150 context_
->GetContextSupport()));
152 return gl_helper_
.get();
155 } // anonymous namespace
158 ImageTransportFactoryAndroid
* ImageTransportFactoryAndroid::GetInstance() {
160 g_factory
= new CmdBufferImageTransportFactory();
165 ImageTransportFactoryAndroid::ImageTransportFactoryAndroid()
166 : context_lost_listener_(new GLContextLostListener()) {}
168 ImageTransportFactoryAndroid::~ImageTransportFactoryAndroid() {}
170 void ImageTransportFactoryAndroid::AddObserver(
171 ImageTransportFactoryAndroidObserver
* observer
) {
172 g_factory_observers
.Get().AddObserver(observer
);
175 void ImageTransportFactoryAndroid::RemoveObserver(
176 ImageTransportFactoryAndroidObserver
* observer
) {
177 g_factory_observers
.Get().RemoveObserver(observer
);
180 void GLContextLostListener::onContextLost() {
181 // Need to post a task because the command buffer client cannot be deleted
182 // from within this callback.
183 LOG(ERROR
) << "Context lost.";
184 base::MessageLoop::current()->PostTask(
186 base::Bind(&GLContextLostListener::DidLoseContext
));
189 void GLContextLostListener::DidLoseContext() {
192 FOR_EACH_OBSERVER(ImageTransportFactoryAndroidObserver
,
193 g_factory_observers
.Get(),
197 } // namespace content