Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GrBatch.h"
      9 #include "GrBatchTarget.h"
     10 #include "GrResourceProvider.h"
     11 
     12 #include "GrMemoryPool.h"
     13 #include "SkSpinlock.h"
     14 
     15 // TODO I noticed a small benefit to using a larger exclusive pool for batches.  Its very small,
     16 // but seems to be mostly consistent.  There is a lot in flux right now, but we should really
     17 // revisit this when batch is everywhere
     18 
     19 
     20 // We use a global pool protected by a mutex(spinlock). Chrome may use the same GrContext on
     21 // different threads. The GrContext is not used concurrently on different threads and there is a
     22 // memory barrier between accesses of a context on different threads. Also, there may be multiple
     23 // GrContexts and those contexts may be in use concurrently on different threads.
     24 namespace {
     25 SK_DECLARE_STATIC_SPINLOCK(gBatchSpinlock);
     26 class MemoryPoolAccessor {
     27 public:
     28     MemoryPoolAccessor() { gBatchSpinlock.acquire(); }
     29 
     30     ~MemoryPoolAccessor() { gBatchSpinlock.release(); }
     31 
     32     GrMemoryPool* pool() const {
     33         static GrMemoryPool gPool(16384, 16384);
     34         return &gPool;
     35     }
     36 };
     37 }
     38 
     39 int32_t GrBatch::gCurrBatchClassID = GrBatch::kIllegalBatchClassID;
     40 
     41 void* GrBatch::operator new(size_t size) {
     42     return MemoryPoolAccessor().pool()->allocate(size);
     43 }
     44 
     45 void GrBatch::operator delete(void* target) {
     46     return MemoryPoolAccessor().pool()->release(target);
     47 }
     48 
     49 void* GrBatch::InstancedHelper::init(GrBatchTarget* batchTarget, GrPrimitiveType primType,
     50                                      size_t vertexStride, const GrIndexBuffer* indexBuffer,
     51                                      int verticesPerInstance, int indicesPerInstance,
     52                                      int instancesToDraw) {
     53     SkASSERT(batchTarget);
     54     if (!indexBuffer) {
     55         return NULL;
     56     }
     57     const GrVertexBuffer* vertexBuffer;
     58     int firstVertex;
     59     int vertexCount = verticesPerInstance * instancesToDraw;
     60     void* vertices = batchTarget->makeVertSpace(vertexStride, vertexCount,
     61                                                 &vertexBuffer, &firstVertex);
     62     if (!vertices) {
     63         SkDebugf("Vertices could not be allocated for instanced rendering.");
     64         return NULL;
     65     }
     66     SkASSERT(vertexBuffer);
     67     size_t ibSize = indexBuffer->gpuMemorySize();
     68     int maxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance));
     69 
     70     fVertices.initInstanced(primType, vertexBuffer, indexBuffer,
     71         firstVertex, verticesPerInstance, indicesPerInstance, instancesToDraw,
     72         maxInstancesPerDraw);
     73     return vertices;
     74 }
     75 
     76 void* GrBatch::QuadHelper::init(GrBatchTarget* batchTarget, size_t vertexStride, int quadsToDraw) {
     77     SkAutoTUnref<const GrIndexBuffer> quadIndexBuffer(
     78         batchTarget->resourceProvider()->refQuadIndexBuffer());
     79     if (!quadIndexBuffer) {
     80         SkDebugf("Could not get quad index buffer.");
     81         return NULL;
     82     }
     83     return this->INHERITED::init(batchTarget, kTriangles_GrPrimitiveType, vertexStride,
     84                                  quadIndexBuffer, kVerticesPerQuad, kIndicesPerQuad, quadsToDraw);
     85 }
     86