Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / renderer_host / image_transport_factory_android.cc
blobcf3ff8b1b7c2e8f6be68cb89a2d001935f55a6b3
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 ImageTransportFactoryAndroid* ImageTransportFactoryAndroid::GetInstance() {
108 if (!g_factory)
109 g_factory = new CmdBufferImageTransportFactory();
111 return g_factory;
114 ImageTransportFactoryAndroid::ImageTransportFactoryAndroid()
115 : context_lost_listener_(new GLContextLostListener()) {}
117 ImageTransportFactoryAndroid::~ImageTransportFactoryAndroid() {}
119 void ImageTransportFactoryAndroid::AddObserver(
120 ImageTransportFactoryAndroidObserver* observer) {
121 g_factory_observers.Get().AddObserver(observer);
124 void ImageTransportFactoryAndroid::RemoveObserver(
125 ImageTransportFactoryAndroidObserver* observer) {
126 g_factory_observers.Get().RemoveObserver(observer);
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));
138 void GLContextLostListener::DidLoseContext() {
139 delete g_factory;
140 g_factory = NULL;
141 FOR_EACH_OBSERVER(ImageTransportFactoryAndroidObserver,
142 g_factory_observers.Get(),
143 OnLostResources());
146 } // namespace content