1 /* 2 * Copyright 2018 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 #ifndef GrMtlGpuCommandBuffer_DEFINED 9 #define GrMtlGpuCommandBuffer_DEFINED 10 11 #include "src/gpu/GrGpuCommandBuffer.h" 12 #include "src/gpu/GrMesh.h" 13 #include "src/gpu/GrOpFlushState.h" 14 #include "src/gpu/mtl/GrMtlGpu.h" 15 16 #import <Metal/Metal.h> 17 18 typedef uint32_t GrColor; 19 class GrMtlBuffer; 20 class GrMtlPipelineState; 21 class GrMtlRenderTarget; 22 23 class GrMtlGpuTextureCommandBuffer : public GrGpuTextureCommandBuffer { 24 public: GrMtlGpuTextureCommandBuffer(GrMtlGpu * gpu,GrTexture * texture,GrSurfaceOrigin origin)25 GrMtlGpuTextureCommandBuffer(GrMtlGpu* gpu, GrTexture* texture, GrSurfaceOrigin origin) 26 : INHERITED(texture, origin) 27 , fGpu(gpu) { 28 } 29 ~GrMtlGpuTextureCommandBuffer()30 ~GrMtlGpuTextureCommandBuffer() override {} 31 copy(GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)32 void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override { 33 fGpu->copySurface(fTexture, src, srcRect, dstPoint); 34 } transferFrom(const SkIRect & srcRect,GrColorType surfaceColorType,GrColorType bufferColorType,GrGpuBuffer * transferBuffer,size_t offset)35 void transferFrom(const SkIRect& srcRect, GrColorType surfaceColorType, 36 GrColorType bufferColorType, GrGpuBuffer* transferBuffer, 37 size_t offset) override { 38 fGpu->transferPixelsFrom(fTexture, srcRect.fLeft, srcRect.fTop, srcRect.width(), 39 srcRect.height(), surfaceColorType, bufferColorType, 40 transferBuffer, offset); 41 } insertEventMarker(const char * msg)42 void insertEventMarker(const char* msg) override {} 43 44 private: 45 GrMtlGpu* fGpu; 46 47 typedef GrGpuTextureCommandBuffer INHERITED; 48 }; 49 50 class GrMtlGpuRTCommandBuffer : public GrGpuRTCommandBuffer, private GrMesh::SendToGpuImpl { 51 public: 52 GrMtlGpuRTCommandBuffer(GrMtlGpu* gpu, GrRenderTarget* rt, GrSurfaceOrigin origin, 53 const SkRect& bounds, 54 const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo, 55 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo); 56 57 ~GrMtlGpuRTCommandBuffer() override; 58 begin()59 void begin() override {} end()60 void end() override {} 61 insertEventMarker(const char * msg)62 void insertEventMarker(const char* msg) override {} 63 64 void initRenderState(id<MTLRenderCommandEncoder>); 65 inlineUpload(GrOpFlushState * state,GrDeferredTextureUploadFn & upload)66 void inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) override { 67 // TODO: this could be more efficient 68 state->doUpload(upload); 69 } 70 void transferFrom(const SkIRect& srcRect, GrColorType textureColorType, 71 GrColorType bufferColorType, GrGpuBuffer* transferBuffer, 72 size_t offset) override; 73 void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; 74 75 void submit(); 76 77 private: gpu()78 GrGpu* gpu() override { return fGpu; } 79 80 GrMtlPipelineState* prepareDrawState( 81 const GrPrimitiveProcessor& primProc, 82 const GrPipeline& pipeline, 83 const GrPipeline::FixedDynamicState* fixedDynamicState, 84 GrPrimitiveType primType); 85 86 void onDraw(const GrPrimitiveProcessor& primProc, 87 const GrPipeline& pipeline, 88 const GrPipeline::FixedDynamicState* fixedDynamicState, 89 const GrPipeline::DynamicStateArrays* dynamicStateArrays, 90 const GrMesh mesh[], 91 int meshCount, 92 const SkRect& bounds) override; 93 94 void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override; 95 96 void onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) override; 97 98 void setupRenderPass(const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo, 99 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo); 100 101 void bindGeometry(const GrBuffer* vertexBuffer, size_t vertexOffset, 102 const GrBuffer* instanceBuffer); 103 104 // GrMesh::SendToGpuImpl methods. These issue the actual Metal draw commands. 105 // Marked final as a hint to the compiler to not use virtual dispatch. 106 void sendMeshToGpu(GrPrimitiveType primType, const GrBuffer* vertexBuffer, int vertexCount, 107 int baseVertex) final; 108 109 void sendIndexedMeshToGpu(GrPrimitiveType primType, const GrBuffer* indexBuffer, int indexCount, 110 int baseIndex, uint16_t /*minIndexValue*/, uint16_t /*maxIndexValue*/, 111 const GrBuffer* vertexBuffer, int baseVertex, 112 GrPrimitiveRestart restart) final; 113 114 void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, 115 int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, 116 int baseInstance) final; 117 118 void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, 119 int baseIndex, const GrBuffer* vertexBuffer, int baseVertex, 120 const GrBuffer* instanceBuffer, int instanceCount, 121 int baseInstance, GrPrimitiveRestart) final; 122 123 void setVertexBuffer(id<MTLRenderCommandEncoder>, const GrMtlBuffer*, size_t offset, 124 size_t index); 125 void resetBufferBindings(); 126 void precreateCmdEncoder(); 127 128 GrMtlGpu* fGpu; 129 // GrRenderTargetProxy bounds 130 #ifdef SK_DEBUG 131 SkRect fRTBounds; 132 #endif 133 134 id<MTLRenderCommandEncoder> fActiveRenderCmdEncoder; 135 MTLRenderPassDescriptor* fRenderPassDesc; 136 SkRect fBounds; 137 size_t fCurrentVertexStride; 138 139 static constexpr size_t kNumBindings = GrMtlUniformHandler::kLastUniformBinding + 3; 140 struct { 141 id<MTLBuffer> fBuffer; 142 size_t fOffset; 143 } fBufferBindings[kNumBindings]; 144 145 typedef GrGpuRTCommandBuffer INHERITED; 146 }; 147 148 #endif 149 150