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 GLHelper
* GetGLHelper() OVERRIDE
;
42 virtual uint32
GetChannelID() OVERRIDE
{
43 return BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
47 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context_
;
48 scoped_ptr
<GLHelper
> gl_helper_
;
50 DISALLOW_COPY_AND_ASSIGN(CmdBufferImageTransportFactory
);
53 CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() {
54 BrowserGpuChannelHostFactory
* factory
=
55 BrowserGpuChannelHostFactory::instance();
56 scoped_refptr
<GpuChannelHost
> gpu_channel_host(factory
->EstablishGpuChannelSync(
57 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
));
58 DCHECK(gpu_channel_host
);
60 blink::WebGraphicsContext3D::Attributes attrs
;
61 attrs
.shareResources
= true;
62 GURL
url("chrome://gpu/ImageTransportFactoryAndroid");
63 static const size_t kBytesPerPixel
= 4;
64 gfx::DeviceDisplayInfo display_info
;
65 size_t full_screen_texture_size_in_bytes
= display_info
.GetDisplayHeight() *
66 display_info
.GetDisplayWidth() *
68 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits
;
69 limits
.command_buffer_size
= 64 * 1024;
70 limits
.start_transfer_buffer_size
= 64 * 1024;
71 limits
.min_transfer_buffer_size
= 64 * 1024;
72 limits
.max_transfer_buffer_size
= std::min(
73 3 * full_screen_texture_size_in_bytes
, kDefaultMaxTransferBufferSize
);
74 limits
.mapped_memory_reclaim_limit
=
75 WebGraphicsContext3DCommandBufferImpl::kNoLimit
;
76 bool lose_context_when_out_of_memory
= false;
78 new WebGraphicsContext3DCommandBufferImpl(0, // offscreen
80 gpu_channel_host
.get(),
82 lose_context_when_out_of_memory
,
85 context_
->setContextLostCallback(context_lost_listener_
.get());
86 if (context_
->makeContextCurrent())
87 context_
->pushGroupMarkerEXT(
88 base::StringPrintf("CmdBufferImageTransportFactory-%p",
89 context_
.get()).c_str());
92 CmdBufferImageTransportFactory::~CmdBufferImageTransportFactory() {
93 context_
->setContextLostCallback(NULL
);
96 GLHelper
* CmdBufferImageTransportFactory::GetGLHelper() {
98 gl_helper_
.reset(new GLHelper(context_
->GetImplementation(),
99 context_
->GetContextSupport()));
101 return gl_helper_
.get();
104 } // anonymous namespace
107 void ImageTransportFactoryAndroid::InitializeForUnitTests(
108 scoped_ptr
<ImageTransportFactoryAndroid
> test_factory
) {
110 g_factory
= test_factory
.release();
114 void ImageTransportFactoryAndroid::TerminateForUnitTests() {
121 ImageTransportFactoryAndroid
* ImageTransportFactoryAndroid::GetInstance() {
123 g_factory
= new CmdBufferImageTransportFactory();
128 ImageTransportFactoryAndroid::ImageTransportFactoryAndroid()
129 : context_lost_listener_(new GLContextLostListener()) {}
131 ImageTransportFactoryAndroid::~ImageTransportFactoryAndroid() {}
133 void ImageTransportFactoryAndroid::AddObserver(
134 ImageTransportFactoryAndroidObserver
* observer
) {
135 g_factory_observers
.Get().AddObserver(observer
);
138 void ImageTransportFactoryAndroid::RemoveObserver(
139 ImageTransportFactoryAndroidObserver
* observer
) {
140 g_factory_observers
.Get().RemoveObserver(observer
);
143 void GLContextLostListener::onContextLost() {
144 // Need to post a task because the command buffer client cannot be deleted
145 // from within this callback.
146 LOG(ERROR
) << "Context lost.";
147 base::MessageLoop::current()->PostTask(
149 base::Bind(&GLContextLostListener::DidLoseContext
));
152 void GLContextLostListener::DidLoseContext() {
155 FOR_EACH_OBSERVER(ImageTransportFactoryAndroidObserver
,
156 g_factory_observers
.Get(),
160 } // namespace content