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 #include "gpu/command_buffer/client/share_group.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/synchronization/lock.h"
      9 #include "gpu/command_buffer/client/gles2_implementation.h"
     10 #include "gpu/command_buffer/client/program_info_manager.h"
     11 #include "gpu/command_buffer/common/id_allocator.h"
     12 
     13 namespace gpu {
     14 namespace gles2 {
     15 
     16 COMPILE_ASSERT(gpu::kInvalidResource == 0,
     17                INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
     18 
     19 // The standard id handler.
     20 class IdHandler : public IdHandlerInterface {
     21  public:
     22   IdHandler() { }
     23   virtual ~IdHandler() { }
     24 
     25   // Overridden from IdHandlerInterface.
     26   virtual void MakeIds(
     27       GLES2Implementation* /* gl_impl */,
     28       GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
     29     if (id_offset == 0) {
     30       for (GLsizei ii = 0; ii < n; ++ii) {
     31         ids[ii] = id_allocator_.AllocateID();
     32       }
     33     } else {
     34       for (GLsizei ii = 0; ii < n; ++ii) {
     35         ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
     36         id_offset = ids[ii] + 1;
     37       }
     38     }
     39   }
     40 
     41   // Overridden from IdHandlerInterface.
     42   virtual bool FreeIds(
     43       GLES2Implementation* gl_impl,
     44       GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
     45     for (GLsizei ii = 0; ii < n; ++ii) {
     46       id_allocator_.FreeID(ids[ii]);
     47     }
     48     (gl_impl->*delete_fn)(n, ids);
     49     // We need to ensure that the delete call is evaluated on the service side
     50     // before any other contexts issue commands using these client ids.
     51     gl_impl->helper()->CommandBufferHelper::Flush();
     52     return true;
     53   }
     54 
     55   // Overridden from IdHandlerInterface.
     56   virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
     57     return id == 0 ? true : id_allocator_.MarkAsUsed(id);
     58   }
     59  protected:
     60   IdAllocator id_allocator_;
     61 };
     62 
     63 // An id handler that require Gen before Bind.
     64 class StrictIdHandler : public IdHandler {
     65  public:
     66   StrictIdHandler() {}
     67   virtual ~StrictIdHandler() {}
     68 
     69   // Overridden from IdHandler.
     70   virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
     71     DCHECK(id == 0 || id_allocator_.InUse(id));
     72     return IdHandler::MarkAsUsedForBind(id);
     73   }
     74 };
     75 
     76 // An id handler for ids that are never reused.
     77 class NonReusedIdHandler : public IdHandlerInterface {
     78  public:
     79   NonReusedIdHandler() : last_id_(0) {}
     80   virtual ~NonReusedIdHandler() {}
     81 
     82   // Overridden from IdHandlerInterface.
     83   virtual void MakeIds(
     84       GLES2Implementation* /* gl_impl */,
     85       GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
     86     for (GLsizei ii = 0; ii < n; ++ii) {
     87       ids[ii] = ++last_id_ + id_offset;
     88     }
     89   }
     90 
     91   // Overridden from IdHandlerInterface.
     92   virtual bool FreeIds(
     93       GLES2Implementation* gl_impl,
     94       GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
     95     // Ids are never freed.
     96     (gl_impl->*delete_fn)(n, ids);
     97     return true;
     98   }
     99 
    100   // Overridden from IdHandlerInterface.
    101   virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE {
    102     // This is only used for Shaders and Programs which have no bind.
    103     return false;
    104   }
    105 
    106  private:
    107   GLuint last_id_;
    108 };
    109 
    110 // An id handler for shared ids.
    111 class SharedIdHandler : public IdHandlerInterface {
    112  public:
    113   SharedIdHandler(
    114       id_namespaces::IdNamespaces id_namespace)
    115       : id_namespace_(id_namespace) {
    116   }
    117 
    118   virtual ~SharedIdHandler() {}
    119 
    120   virtual void MakeIds(GLES2Implementation* gl_impl,
    121                        GLuint id_offset,
    122                        GLsizei n,
    123                        GLuint* ids) OVERRIDE {
    124     gl_impl->GenSharedIdsCHROMIUM(id_namespace_, id_offset, n, ids);
    125   }
    126 
    127   virtual bool FreeIds(GLES2Implementation* gl_impl,
    128                        GLsizei n,
    129                        const GLuint* ids,
    130                        DeleteFn delete_fn) OVERRIDE {
    131     gl_impl->DeleteSharedIdsCHROMIUM(id_namespace_, n, ids);
    132     (gl_impl->*delete_fn)(n, ids);
    133     // We need to ensure that the delete call is evaluated on the service side
    134     // before any other contexts issue commands using these client ids.
    135     gl_impl->helper()->CommandBufferHelper::Flush();
    136     return true;
    137   }
    138 
    139   virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
    140     // This has no meaning for shared resources.
    141     return true;
    142   }
    143 
    144  private:
    145   id_namespaces::IdNamespaces id_namespace_;
    146 };
    147 
    148 class ThreadSafeIdHandlerWrapper : public IdHandlerInterface {
    149  public:
    150   ThreadSafeIdHandlerWrapper(IdHandlerInterface* id_handler)
    151       : id_handler_(id_handler) {
    152   }
    153   virtual ~ThreadSafeIdHandlerWrapper() { }
    154 
    155   // Overridden from IdHandlerInterface.
    156   virtual void MakeIds(GLES2Implementation* gl_impl,
    157                        GLuint id_offset,
    158                        GLsizei n,
    159                        GLuint* ids) OVERRIDE {
    160     base::AutoLock auto_lock(lock_);
    161     id_handler_->MakeIds(gl_impl, id_offset, n, ids);
    162   }
    163 
    164   // Overridden from IdHandlerInterface.
    165   virtual bool FreeIds(GLES2Implementation* gl_impl,
    166                        GLsizei n,
    167                        const GLuint* ids,
    168                        DeleteFn delete_fn) OVERRIDE {
    169     base::AutoLock auto_lock(lock_);
    170     return id_handler_->FreeIds(gl_impl, n, ids, delete_fn);
    171   }
    172 
    173   // Overridden from IdHandlerInterface.
    174   virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
    175     base::AutoLock auto_lock(lock_);
    176     return id_handler_->MarkAsUsedForBind(id);
    177   }
    178 
    179  private:
    180    scoped_ptr<IdHandlerInterface> id_handler_;
    181    base::Lock lock_;
    182 };
    183 
    184 ShareGroup::ShareGroup(bool bind_generates_resource)
    185     : bind_generates_resource_(bind_generates_resource) {
    186   if (bind_generates_resource) {
    187     for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
    188       if (i == id_namespaces::kProgramsAndShaders) {
    189         id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
    190             new NonReusedIdHandler()));
    191       } else {
    192         id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
    193             new IdHandler()));
    194       }
    195     }
    196   } else {
    197     for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
    198       if (i == id_namespaces::kProgramsAndShaders) {
    199         id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
    200             new NonReusedIdHandler()));
    201       } else {
    202         id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
    203             new StrictIdHandler()));
    204       }
    205     }
    206   }
    207   program_info_manager_.reset(ProgramInfoManager::Create(false));
    208 }
    209 
    210 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
    211   program_info_manager_.reset(manager);
    212 }
    213 
    214 ShareGroup::~ShareGroup() {}
    215 
    216 }  // namespace gles2
    217 }  // namespace gpu
    218