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#ifndef CONTENT_COMMON_GPU_CLIENT_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_ 6#define CONTENT_COMMON_GPU_CLIENT_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_ 7 8#include <string> 9#include <vector> 10 11#include "base/callback.h" 12#include "base/memory/scoped_ptr.h" 13#include "base/memory/weak_ptr.h" 14#include "base/synchronization/lock.h" 15#include "content/common/content_export.h" 16#include "content/common/gpu/client/command_buffer_proxy_impl.h" 17#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 18#include "third_party/WebKit/public/platform/WebString.h" 19#include "ui/gfx/native_widget_types.h" 20#include "ui/gl/gpu_preference.h" 21#include "url/gurl.h" 22#include "webkit/common/gpu/webgraphicscontext3d_impl.h" 23 24namespace gpu { 25 26class ContextSupport; 27class TransferBuffer; 28 29namespace gles2 { 30class GLES2CmdHelper; 31class GLES2Implementation; 32class GLES2Interface; 33} 34} 35 36namespace content { 37class GpuChannelHost; 38 39const size_t kDefaultCommandBufferSize = 1024 * 1024; 40const size_t kDefaultStartTransferBufferSize = 1 * 1024 * 1024; 41const size_t kDefaultMinTransferBufferSize = 1 * 256 * 1024; 42const size_t kDefaultMaxTransferBufferSize = 16 * 1024 * 1024; 43 44class WebGraphicsContext3DCommandBufferImpl 45 : public webkit::gpu::WebGraphicsContext3DImpl { 46 public: 47 enum MappedMemoryReclaimLimit { 48 kNoLimit = 0, 49 }; 50 51 struct CONTENT_EXPORT SharedMemoryLimits { 52 SharedMemoryLimits(); 53 54 size_t command_buffer_size; 55 size_t start_transfer_buffer_size; 56 size_t min_transfer_buffer_size; 57 size_t max_transfer_buffer_size; 58 size_t mapped_memory_reclaim_limit; 59 }; 60 61 class ShareGroup : public base::RefCountedThreadSafe<ShareGroup> { 62 public: 63 ShareGroup(); 64 65 WebGraphicsContext3DCommandBufferImpl* GetAnyContextLocked() { 66 // In order to ensure that the context returned is not removed while 67 // in use, the share group's lock should be aquired before calling this 68 // function. 69 lock_.AssertAcquired(); 70 if (contexts_.empty()) 71 return NULL; 72 return contexts_.front(); 73 } 74 75 void AddContextLocked(WebGraphicsContext3DCommandBufferImpl* context) { 76 lock_.AssertAcquired(); 77 contexts_.push_back(context); 78 } 79 80 void RemoveContext(WebGraphicsContext3DCommandBufferImpl* context) { 81 base::AutoLock auto_lock(lock_); 82 contexts_.erase(std::remove(contexts_.begin(), contexts_.end(), context), 83 contexts_.end()); 84 } 85 86 void RemoveAllContexts() { 87 base::AutoLock auto_lock(lock_); 88 contexts_.clear(); 89 } 90 91 base::Lock& lock() { 92 return lock_; 93 } 94 95 private: 96 friend class base::RefCountedThreadSafe<ShareGroup>; 97 virtual ~ShareGroup(); 98 99 std::vector<WebGraphicsContext3DCommandBufferImpl*> contexts_; 100 base::Lock lock_; 101 102 DISALLOW_COPY_AND_ASSIGN(ShareGroup); 103 }; 104 105 WebGraphicsContext3DCommandBufferImpl( 106 int surface_id, 107 const GURL& active_url, 108 GpuChannelHost* host, 109 const Attributes& attributes, 110 bool lose_context_when_out_of_memory, 111 const SharedMemoryLimits& limits, 112 WebGraphicsContext3DCommandBufferImpl* share_context); 113 114 virtual ~WebGraphicsContext3DCommandBufferImpl(); 115 116 CommandBufferProxyImpl* GetCommandBufferProxy() { 117 return command_buffer_.get(); 118 } 119 120 CONTENT_EXPORT gpu::ContextSupport* GetContextSupport(); 121 122 gpu::gles2::GLES2Implementation* GetImplementation() { 123 return real_gl_.get(); 124 } 125 126 // Return true if GPU process reported context lost or there was a 127 // problem communicating with the GPU process. 128 bool IsCommandBufferContextLost(); 129 130 // Create & initialize a WebGraphicsContext3DCommandBufferImpl. Return NULL 131 // on any failure. 132 static CONTENT_EXPORT WebGraphicsContext3DCommandBufferImpl* 133 CreateOffscreenContext( 134 GpuChannelHost* host, 135 const WebGraphicsContext3D::Attributes& attributes, 136 bool lose_context_when_out_of_memory, 137 const GURL& active_url, 138 const SharedMemoryLimits& limits, 139 WebGraphicsContext3DCommandBufferImpl* share_context); 140 141 size_t GetMappedMemoryLimit() { 142 return mem_limits_.mapped_memory_reclaim_limit; 143 } 144 145 // WebGraphicsContext3DImpl methods 146 virtual bool InitializeOnCurrentThread() OVERRIDE; 147 148 //---------------------------------------------------------------------- 149 // WebGraphicsContext3D methods 150 virtual bool isContextLost(); 151 152 virtual WGC3Denum getGraphicsResetStatusARB(); 153 154 private: 155 // These are the same error codes as used by EGL. 156 enum Error { 157 SUCCESS = 0x3000, 158 BAD_ATTRIBUTE = 0x3004, 159 CONTEXT_LOST = 0x300E 160 }; 161 162 // Initialize the underlying GL context. May be called multiple times; second 163 // and subsequent calls are ignored. Must be called from the thread that is 164 // going to use this object to issue GL commands (which might not be the main 165 // thread). 166 bool MaybeInitializeGL(); 167 168 bool InitializeCommandBuffer(bool onscreen, 169 WebGraphicsContext3DCommandBufferImpl* share_context); 170 171 void Destroy(); 172 173 // Create a CommandBufferProxy that renders directly to a view. The view and 174 // the associated window must not be destroyed until the returned 175 // CommandBufferProxy has been destroyed, otherwise the GPU process might 176 // attempt to render to an invalid window handle. 177 // 178 // NOTE: on Mac OS X, this entry point is only used to set up the 179 // accelerated compositor's output. On this platform, we actually pass 180 // a gfx::PluginWindowHandle in place of the gfx::NativeViewId, 181 // because the facility to allocate a fake PluginWindowHandle is 182 // already in place. We could add more entry points and messages to 183 // allocate both fake PluginWindowHandles and NativeViewIds and map 184 // from fake NativeViewIds to PluginWindowHandles, but this seems like 185 // unnecessary complexity at the moment. 186 bool CreateContext(bool onscreen); 187 188 virtual void OnGpuChannelLost(); 189 190 bool lose_context_when_out_of_memory_; 191 blink::WebGraphicsContext3D::Attributes attributes_; 192 193 bool visible_; 194 195 // State needed by MaybeInitializeGL. 196 scoped_refptr<GpuChannelHost> host_; 197 int32 surface_id_; 198 GURL active_url_; 199 200 gfx::GpuPreference gpu_preference_; 201 202 scoped_ptr<CommandBufferProxyImpl> command_buffer_; 203 scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_; 204 scoped_ptr<gpu::TransferBuffer> transfer_buffer_; 205 scoped_ptr<gpu::gles2::GLES2Implementation> real_gl_; 206 scoped_ptr<gpu::gles2::GLES2Interface> trace_gl_; 207 Error last_error_; 208 SharedMemoryLimits mem_limits_; 209 scoped_refptr<ShareGroup> share_group_; 210 211 // Member variables should appear before the WeakPtrFactory, to ensure 212 // that any WeakPtrs to Controller are invalidated before its members 213 // variable's destructors are executed, rendering them invalid. 214 base::WeakPtrFactory<WebGraphicsContext3DCommandBufferImpl> weak_ptr_factory_; 215}; 216 217} // namespace content 218 219#endif // CONTENT_COMMON_GPU_CLIENT_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_ 220