Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2016 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 "GrBuffer.h"
      9 #include "GrGpu.h"
     10 #include "GrCaps.h"
     11 
     12 GrBuffer* GrBuffer::CreateCPUBacked(GrGpu* gpu, size_t sizeInBytes, GrBufferType intendedType,
     13                                     const void* data) {
     14     SkASSERT(GrBufferTypeIsVertexOrIndex(intendedType));
     15     void* cpuData;
     16     if (gpu->caps()->mustClearUploadedBufferData()) {
     17         cpuData = sk_calloc_throw(sizeInBytes);
     18     } else {
     19         cpuData = sk_malloc_throw(sizeInBytes);
     20     }
     21     if (data) {
     22         memcpy(cpuData, data, sizeInBytes);
     23     }
     24     return new GrBuffer(gpu, sizeInBytes, intendedType, cpuData);
     25 }
     26 
     27 GrBuffer::GrBuffer(GrGpu* gpu, size_t sizeInBytes, GrBufferType type, void* cpuData)
     28     : INHERITED(gpu)
     29     , fMapPtr(nullptr)
     30     , fSizeInBytes(sizeInBytes)
     31     , fAccessPattern(kDynamic_GrAccessPattern)
     32     , fCPUData(cpuData)
     33     , fIntendedType(type) {
     34     this->registerWithCache(SkBudgeted::kNo);
     35 }
     36 
     37 GrBuffer::GrBuffer(GrGpu* gpu, size_t sizeInBytes, GrBufferType type, GrAccessPattern pattern)
     38     : INHERITED(gpu)
     39     , fMapPtr(nullptr)
     40     , fSizeInBytes(sizeInBytes)
     41     , fAccessPattern(pattern)
     42     , fCPUData(nullptr)
     43     , fIntendedType(type) {
     44     // Subclass registers with cache.
     45 }
     46 
     47 void GrBuffer::ComputeScratchKeyForDynamicVBO(size_t size, GrBufferType intendedType,
     48                                               GrScratchKey* key) {
     49     static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
     50     GrScratchKey::Builder builder(key, kType, 1 + (sizeof(size_t) + 3) / 4);
     51     // TODO: There's not always reason to cache a buffer by type. In some (all?) APIs it's just
     52     // a chunk of memory we can use/reuse for any type of data. We really only need to
     53     // differentiate between the "read" types (e.g. kGpuToCpu_BufferType) and "draw" types.
     54     builder[0] = intendedType;
     55     builder[1] = (uint32_t)size;
     56     if (sizeof(size_t) > 4) {
     57         builder[2] = (uint32_t)((uint64_t)size >> 32);
     58     }
     59 }
     60 
     61 bool GrBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
     62     SkASSERT(this->isCPUBacked());
     63     memcpy(fCPUData, src, srcSizeInBytes);
     64     return true;
     65 }
     66 
     67 void GrBuffer::computeScratchKey(GrScratchKey* key) const {
     68     if (!this->isCPUBacked() && SkIsPow2(fSizeInBytes) &&
     69         kDynamic_GrAccessPattern == fAccessPattern) {
     70         ComputeScratchKeyForDynamicVBO(fSizeInBytes, fIntendedType, key);
     71     }
     72 }
     73