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 "GrGpuCommandBuffer.h"
9
10 #include "GrContext.h"
11 #include "GrCaps.h"
12 #include "GrFixedClip.h"
13 #include "GrGpu.h"
14 #include "GrMesh.h"
15 #include "GrPrimitiveProcessor.h"
16 #include "GrRenderTarget.h"
17 #include "SkRect.h"
18
clear(const GrFixedClip & clip,const SkPMColor4f & color)19 void GrGpuRTCommandBuffer::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
20 SkASSERT(fRenderTarget);
21 // A clear at this level will always be a true clear, so make sure clears were not supposed to
22 // be redirected to draws instead
23 SkASSERT(!this->gpu()->caps()->performColorClearsAsDraws());
24 SkASSERT(!clip.scissorEnabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
25 this->onClear(clip, color);
26 }
27
clearStencilClip(const GrFixedClip & clip,bool insideStencilMask)28 void GrGpuRTCommandBuffer::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
29 // As above, make sure the stencil clear wasn't supposed to be a draw rect with stencil settings
30 SkASSERT(!this->gpu()->caps()->performStencilClearsAsDraws());
31 this->onClearStencilClip(clip, insideStencilMask);
32 }
33
draw(const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline,const GrPipeline::FixedDynamicState * fixedDynamicState,const GrPipeline::DynamicStateArrays * dynamicStateArrays,const GrMesh meshes[],int meshCount,const SkRect & bounds)34 bool GrGpuRTCommandBuffer::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
35 const GrPipeline::FixedDynamicState* fixedDynamicState,
36 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
37 const GrMesh meshes[], int meshCount, const SkRect& bounds) {
38 #ifdef SK_DEBUG
39 SkASSERT(!primProc.hasInstanceAttributes() || this->gpu()->caps()->instanceAttribSupport());
40 for (int i = 0; i < meshCount; ++i) {
41 SkASSERT(!GrPrimTypeRequiresGeometryShaderSupport(meshes[i].primitiveType()) ||
42 this->gpu()->caps()->shaderCaps()->geometryShaderSupport());
43 SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
44 SkASSERT(primProc.hasInstanceAttributes() == meshes[i].isInstanced());
45 }
46 #endif
47 SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
48 (dynamicStateArrays && dynamicStateArrays->fScissorRects));
49
50 auto resourceProvider = this->gpu()->getContext()->contextPriv().resourceProvider();
51
52 if (pipeline.isBad()) {
53 return false;
54 }
55 if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
56 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
57 if (!fixedDynamicState->fPrimitiveProcessorTextures[i]->instantiate(resourceProvider)) {
58 return false;
59 }
60 }
61 }
62 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
63 int n = primProc.numTextureSamplers() * meshCount;
64 const auto* textures = dynamicStateArrays->fPrimitiveProcessorTextures;
65 for (int i = 0; i < n; ++i) {
66 if (!textures[i]->instantiate(resourceProvider)) {
67 return false;
68 }
69 }
70 #ifdef SK_DEBUG
71 SkASSERT(meshCount >= 1);
72 const GrTextureProxy* const* primProcProxies =
73 dynamicStateArrays->fPrimitiveProcessorTextures;
74 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
75 const GrBackendFormat& format = primProcProxies[i]->backendFormat();
76 GrTextureType type = primProcProxies[i]->textureType();
77 GrPixelConfig config = primProcProxies[i]->config();
78 for (int j = 1; j < meshCount; ++j) {
79 const GrTextureProxy* testProxy =
80 primProcProxies[j*primProc.numTextureSamplers() + i];
81 SkASSERT(testProxy->backendFormat() == format);
82 SkASSERT(testProxy->textureType() == type);
83 SkASSERT(testProxy->config() == config);
84 }
85 }
86 #endif
87
88 }
89
90 if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
91 this->gpu()->stats()->incNumFailedDraws();
92 return false;
93 }
94 this->onDraw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshes, meshCount,
95 bounds);
96 return true;
97 }
98