Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / image_transport_factory_android.cc
blobb7adb06b67124b8964be878bb9193e70036a8181
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"
18 namespace content {
20 base::LazyInstance<ObserverList<ImageTransportFactoryAndroidObserver> >::Leaky
21 g_factory_observers = LAZY_INSTANCE_INITIALIZER;
23 class GLContextLostListener
24 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
25 public:
26 // WebGraphicsContextLostCallback implementation.
27 virtual void onContextLost() OVERRIDE;
28 private:
29 static void DidLoseContext();
32 namespace {
34 static ImageTransportFactoryAndroid* g_factory = NULL;
36 class CmdBufferImageTransportFactory : public ImageTransportFactoryAndroid {
37 public:
38 CmdBufferImageTransportFactory();
39 virtual ~CmdBufferImageTransportFactory();
41 virtual GLHelper* GetGLHelper() OVERRIDE;
42 virtual uint32 GetChannelID() OVERRIDE {
43 return BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
46 private:
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() *
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());
92 CmdBufferImageTransportFactory::~CmdBufferImageTransportFactory() {
93 context_->setContextLostCallback(NULL);
96 GLHelper* CmdBufferImageTransportFactory::GetGLHelper() {
97 if (!gl_helper_)
98 gl_helper_.reset(new GLHelper(context_->GetImplementation(),
99 context_->GetContextSupport()));
101 return gl_helper_.get();
104 } // anonymous namespace
106 // static
107 void ImageTransportFactoryAndroid::InitializeForUnitTests(
108 scoped_ptr<ImageTransportFactoryAndroid> test_factory) {
109 DCHECK(!g_factory);
110 g_factory = test_factory.release();
113 // static
114 void ImageTransportFactoryAndroid::TerminateForUnitTests() {
115 DCHECK(g_factory);
116 delete g_factory;
117 g_factory = NULL;
120 // static
121 ImageTransportFactoryAndroid* ImageTransportFactoryAndroid::GetInstance() {
122 if (!g_factory)
123 g_factory = new CmdBufferImageTransportFactory();
125 return g_factory;
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(
148 FROM_HERE,
149 base::Bind(&GLContextLostListener::DidLoseContext));
152 void GLContextLostListener::DidLoseContext() {
153 delete g_factory;
154 g_factory = NULL;
155 FOR_EACH_OBSERVER(ImageTransportFactoryAndroidObserver,
156 g_factory_observers.Get(),
157 OnLostResources());
160 } // namespace content