Home | History | Annotate | Download | only in client
      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