Add a NULL-check in Android's CompositorImpl::OnSurfaceUpdated()
[chromium-blink-merge.git] / content / browser / renderer_host / compositor_impl_android.cc
blob9d625ec7b529a039180ca8b0c25d0a7c9139d583
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/compositor_impl_android.h"
7 #include <android/native_window_jni.h>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
12 #include "content/browser/gpu/gpu_surface_tracker.h"
13 #include "content/browser/renderer_host/image_transport_factory_android.h"
14 #include "content/common/gpu/client/gpu_channel_host.h"
15 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
16 #include "content/common/gpu/gpu_process_launch_causes.h"
17 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h"
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSupport.h"
19 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurface.h"
21 namespace {
23 static bool g_initialized = false;
25 // Adapts a pure WebGraphicsContext3D into a WebCompositorOutputSurface.
26 class WebGraphicsContextToOutputSurfaceAdapter :
27 public WebKit::WebCompositorOutputSurface {
28 public:
29 explicit WebGraphicsContextToOutputSurfaceAdapter(
30 WebKit::WebGraphicsContext3D* context)
31 : m_context3D(context)
32 , m_client(0)
36 virtual bool bindToClient(
37 WebKit::WebCompositorOutputSurfaceClient* client) OVERRIDE
39 DCHECK(client);
40 if (!m_context3D->makeContextCurrent())
41 return false;
42 m_client = client;
43 return true;
46 virtual const Capabilities& capabilities() const OVERRIDE
48 return m_capabilities;
51 virtual WebKit::WebGraphicsContext3D* context3D() const OVERRIDE
53 return m_context3D.get();
56 virtual void sendFrameToParentCompositor(
57 const WebKit::WebCompositorFrame&) OVERRIDE
61 private:
62 scoped_ptr<WebKit::WebGraphicsContext3D> m_context3D;
63 Capabilities m_capabilities;
64 WebKit::WebCompositorOutputSurfaceClient* m_client;
67 } // anonymous namespace
69 namespace content {
71 // static
72 Compositor* Compositor::Create() {
73 return new CompositorImpl();
76 // static
77 void Compositor::Initialize() {
78 g_initialized = true;
79 WebKit::Platform::current()->compositorSupport()->initialize(NULL);
82 // static
83 bool CompositorImpl::IsInitialized() {
84 return g_initialized;
87 CompositorImpl::CompositorImpl()
88 : window_(NULL),
89 surface_id_(0) {
90 root_layer_.reset(
91 WebKit::Platform::current()->compositorSupport()->createLayer());
94 CompositorImpl::~CompositorImpl() {
97 void CompositorImpl::OnSurfaceUpdated(
98 const SurfacePresentedCallback& callback) {
99 if (host_->get())
100 host_->composite();
101 // TODO(sievers): Let RWHV do this
102 uint32 sync_point =
103 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
104 callback.Run(sync_point);
107 void CompositorImpl::SetRootLayer(WebKit::WebLayer* root_layer) {
108 root_layer_->removeAllChildren();
109 root_layer_->addChild(root_layer);
112 void CompositorImpl::SetWindowSurface(ANativeWindow* window) {
113 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();
115 if (window_) {
116 tracker->RemoveSurface(surface_id_);
117 ANativeWindow_release(window_);
118 window_ = NULL;
119 surface_id_ = 0;
120 size_ = gfx::Size();
123 if (window) {
124 window_ = window;
125 ANativeWindow_acquire(window);
126 surface_id_ = tracker->AddSurfaceForNativeWidget(window);
127 tracker->SetSurfaceHandle(
128 surface_id_,
129 gfx::GLSurfaceHandle(gfx::kDummyPluginWindow, false));
131 WebKit::WebLayerTreeView::Settings settings;
132 settings.refreshRate = 60.0;
133 WebKit::WebCompositorSupport* compositor_support =
134 WebKit::Platform::current()->compositorSupport();
135 host_.reset(
136 compositor_support->createLayerTreeView(this, *root_layer_, settings));
137 host_->setVisible(true);
138 host_->setSurfaceReady();
142 void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
143 if (size_ == size)
144 return;
146 size_ = size;
147 host_->setViewportSize(size);
148 root_layer_->setBounds(size);
151 void CompositorImpl::updateAnimations(double frameBeginTime) {
154 void CompositorImpl::layout() {
157 void CompositorImpl::applyScrollAndScale(const WebKit::WebSize& scrollDelta,
158 float scaleFactor) {
161 WebKit::WebCompositorOutputSurface* CompositorImpl::createOutputSurface() {
162 WebKit::WebGraphicsContext3D::Attributes attrs;
163 attrs.shareResources = true;
164 GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance();
165 GURL url("chrome://gpu/Compositor::createContext3D");
166 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client;
167 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
168 new WebGraphicsContext3DCommandBufferImpl(
169 surface_id_,
170 url,
171 factory,
172 swap_client));
173 if (!context->Initialize(
174 attrs,
175 false,
176 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) {
177 LOG(ERROR) << "Failed to create 3D context for compositor.";
178 return NULL;
181 return new WebGraphicsContextToOutputSurfaceAdapter(context.release());
184 void CompositorImpl::didRecreateOutputSurface(bool success) {
187 void CompositorImpl::didCommit() {
190 void CompositorImpl::didCommitAndDrawFrame() {
193 void CompositorImpl::didCompleteSwapBuffers() {
196 void CompositorImpl::scheduleComposite() {
199 } // namespace content