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 24 namespace gpu { 25 26 class ContextSupport; 27 class TransferBuffer; 28 29 namespace gles2 { 30 class GLES2CmdHelper; 31 class GLES2Implementation; 32 class GLES2Interface; 33 } 34 } 35 36 namespace content { 37 class GpuChannelHost; 38 39 const size_t kDefaultCommandBufferSize = 1024 * 1024; 40 const size_t kDefaultStartTransferBufferSize = 1 * 1024 * 1024; 41 const size_t kDefaultMinTransferBufferSize = 1 * 256 * 1024; 42 const size_t kDefaultMaxTransferBufferSize = 16 * 1024 * 1024; 43 44 class 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 //---------------------------------------------------------------------- 146 // WebGraphicsContext3D methods 147 148 // Must be called after initialize() and before any of the following methods. 149 // Permanently binds to the first calling thread. Returns false if the 150 // graphics context fails to create. Do not call from more than one thread. 151 virtual bool makeContextCurrent(); 152 153 virtual bool isContextLost(); 154 155 virtual WGC3Denum getGraphicsResetStatusARB(); 156 157 private: 158 // These are the same error codes as used by EGL. 159 enum Error { 160 SUCCESS = 0x3000, 161 BAD_ATTRIBUTE = 0x3004, 162 CONTEXT_LOST = 0x300E 163 }; 164 // WebGraphicsContext3DCommandBufferImpl configuration attributes. Those in 165 // the 16-bit range are the same as used by EGL. Those outside the 16-bit 166 // range are unique to Chromium. Attributes are matched using a closest fit 167 // algorithm. 168 // Changes to this enum should also be copied to 169 // gpu/command_buffer/common/gles2_cmd_utils.cc and to 170 // gpu/command_buffer/client/gl_in_process_context.cc 171 enum Attribute { 172 ALPHA_SIZE = 0x3021, 173 BLUE_SIZE = 0x3022, 174 GREEN_SIZE = 0x3023, 175 RED_SIZE = 0x3024, 176 DEPTH_SIZE = 0x3025, 177 STENCIL_SIZE = 0x3026, 178 SAMPLES = 0x3031, 179 SAMPLE_BUFFERS = 0x3032, 180 HEIGHT = 0x3056, 181 WIDTH = 0x3057, 182 NONE = 0x3038, // Attrib list = terminator 183 SHARE_RESOURCES = 0x10000, 184 BIND_GENERATES_RESOURCES = 0x10001, 185 FAIL_IF_MAJOR_PERF_CAVEAT = 0x10002, 186 LOSE_CONTEXT_WHEN_OUT_OF_MEMORY = 0x10003, 187 }; 188 189 // Initialize the underlying GL context. May be called multiple times; second 190 // and subsequent calls are ignored. Must be called from the thread that is 191 // going to use this object to issue GL commands (which might not be the main 192 // thread). 193 bool MaybeInitializeGL(); 194 195 bool InitializeCommandBuffer(bool onscreen, 196 WebGraphicsContext3DCommandBufferImpl* share_context); 197 198 void Destroy(); 199 200 // Create a CommandBufferProxy that renders directly to a view. The view and 201 // the associated window must not be destroyed until the returned 202 // CommandBufferProxy has been destroyed, otherwise the GPU process might 203 // attempt to render to an invalid window handle. 204 // 205 // NOTE: on Mac OS X, this entry point is only used to set up the 206 // accelerated compositor's output. On this platform, we actually pass 207 // a gfx::PluginWindowHandle in place of the gfx::NativeViewId, 208 // because the facility to allocate a fake PluginWindowHandle is 209 // already in place. We could add more entry points and messages to 210 // allocate both fake PluginWindowHandles and NativeViewIds and map 211 // from fake NativeViewIds to PluginWindowHandles, but this seems like 212 // unnecessary complexity at the moment. 213 bool CreateContext(bool onscreen); 214 215 virtual void OnGpuChannelLost(); 216 217 bool lose_context_when_out_of_memory_; 218 blink::WebGraphicsContext3D::Attributes attributes_; 219 220 bool visible_; 221 222 // State needed by MaybeInitializeGL. 223 scoped_refptr<GpuChannelHost> host_; 224 int32 surface_id_; 225 GURL active_url_; 226 227 gfx::GpuPreference gpu_preference_; 228 229 base::WeakPtrFactory<WebGraphicsContext3DCommandBufferImpl> weak_ptr_factory_; 230 231 scoped_ptr<CommandBufferProxyImpl> command_buffer_; 232 scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_; 233 scoped_ptr<gpu::TransferBuffer> transfer_buffer_; 234 scoped_ptr<gpu::gles2::GLES2Implementation> real_gl_; 235 scoped_ptr<gpu::gles2::GLES2Interface> trace_gl_; 236 Error last_error_; 237 SharedMemoryLimits mem_limits_; 238 scoped_refptr<ShareGroup> share_group_; 239 }; 240 241 } // namespace content 242 243 #endif // CONTENT_COMMON_GPU_CLIENT_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_ 244