Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / image_transport_factory_android.cc
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.
4
5 #include "content/browser/renderer_host/image_transport_factory_android.h"
6
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"
17
18 namespace content {
19
20 base::LazyInstance<ObserverList<ImageTransportFactoryAndroidObserver> >::Leaky
21     g_factory_observers = LAZY_INSTANCE_INITIALIZER;
22
23 class GLContextLostListener
24     : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
25  public:
26   // WebGraphicsContextLostCallback implementation.
27   virtual void onContextLost() OVERRIDE;
28  private:
29   static void DidLoseContext();
30 };
31
32 namespace {
33
34 static ImageTransportFactoryAndroid* g_factory = NULL;
35
36 class CmdBufferImageTransportFactory : public ImageTransportFactoryAndroid {
37  public:
38   CmdBufferImageTransportFactory();
39   virtual ~CmdBufferImageTransportFactory();
40
41   virtual GLHelper* GetGLHelper() OVERRIDE;
42   virtual uint32 GetChannelID() OVERRIDE {
43     return BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
44   }
45
46  private:
47   scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context_;
48   scoped_ptr<GLHelper> gl_helper_;
49
50   DISALLOW_COPY_AND_ASSIGN(CmdBufferImageTransportFactory);
51 };
52
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);
59
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() *
67                                              kBytesPerPixel;
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;
77   context_.reset(
78       new WebGraphicsContext3DCommandBufferImpl(0,  // offscreen
79                                                 url,
80                                                 gpu_channel_host.get(),
81                                                 attrs,
82                                                 lose_context_when_out_of_memory,
83                                                 limits,
84                                                 NULL));
85   context_->setContextLostCallback(context_lost_listener_.get());
86   if (context_->makeContextCurrent())
87     context_->pushGroupMarkerEXT(
88         base::StringPrintf("CmdBufferImageTransportFactory-%p",
89                            context_.get()).c_str());
90 }
91
92 CmdBufferImageTransportFactory::~CmdBufferImageTransportFactory() {
93   context_->setContextLostCallback(NULL);
94 }
95
96 GLHelper* CmdBufferImageTransportFactory::GetGLHelper() {
97   if (!gl_helper_)
98     gl_helper_.reset(new GLHelper(context_->GetImplementation(),
99                                   context_->GetContextSupport()));
100
101   return gl_helper_.get();
102 }
103
104 }  // anonymous namespace
105
106 // static
107 ImageTransportFactoryAndroid* ImageTransportFactoryAndroid::GetInstance() {
108   if (!g_factory)
109     g_factory = new CmdBufferImageTransportFactory();
110
111   return g_factory;
112 }
113
114 ImageTransportFactoryAndroid::ImageTransportFactoryAndroid()
115     : context_lost_listener_(new GLContextLostListener()) {}
116
117 ImageTransportFactoryAndroid::~ImageTransportFactoryAndroid() {}
118
119 void ImageTransportFactoryAndroid::AddObserver(
120     ImageTransportFactoryAndroidObserver* observer) {
121   g_factory_observers.Get().AddObserver(observer);
122 }
123
124 void ImageTransportFactoryAndroid::RemoveObserver(
125     ImageTransportFactoryAndroidObserver* observer) {
126   g_factory_observers.Get().RemoveObserver(observer);
127 }
128
129 void GLContextLostListener::onContextLost() {
130   // Need to post a task because the command buffer client cannot be deleted
131   // from within this callback.
132   LOG(ERROR) << "Context lost.";
133   base::MessageLoop::current()->PostTask(
134       FROM_HERE,
135       base::Bind(&GLContextLostListener::DidLoseContext));
136 }
137
138 void GLContextLostListener::DidLoseContext() {
139   delete g_factory;
140   g_factory = NULL;
141   FOR_EACH_OBSERVER(ImageTransportFactoryAndroidObserver,
142       g_factory_observers.Get(),
143       OnLostResources());
144 }
145
146 } // namespace content