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 "src/gpu/GrOpsRenderPass.h"
9
10 #include "include/core/SkRect.h"
11 #include "include/gpu/GrContext.h"
12 #include "src/gpu/GrCaps.h"
13 #include "src/gpu/GrContextPriv.h"
14 #include "src/gpu/GrFixedClip.h"
15 #include "src/gpu/GrGpu.h"
16 #include "src/gpu/GrMesh.h"
17 #include "src/gpu/GrPrimitiveProcessor.h"
18 #include "src/gpu/GrProgramInfo.h"
19 #include "src/gpu/GrRenderTarget.h"
20 #include "src/gpu/GrRenderTargetPriv.h"
21 #include "src/gpu/GrTexturePriv.h"
22
clear(const GrFixedClip & clip,const SkPMColor4f & color)23 void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
24 SkASSERT(fRenderTarget);
25 // A clear at this level will always be a true clear, so make sure clears were not supposed to
26 // be redirected to draws instead
27 SkASSERT(!this->gpu()->caps()->performColorClearsAsDraws());
28 SkASSERT(!clip.scissorEnabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
29 fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
30 this->onClear(clip, color);
31 }
32
clearStencilClip(const GrFixedClip & clip,bool insideStencilMask)33 void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
34 // As above, make sure the stencil clear wasn't supposed to be a draw rect with stencil settings
35 SkASSERT(!this->gpu()->caps()->performStencilClearsAsDraws());
36 fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
37 this->onClearStencilClip(clip, insideStencilMask);
38 }
39
executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable)40 void GrOpsRenderPass::executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable) {
41 fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
42 this->onExecuteDrawable(std::move(drawable));
43 }
44
bindPipeline(const GrProgramInfo & programInfo,const SkRect & drawBounds)45 void GrOpsRenderPass::bindPipeline(const GrProgramInfo& programInfo, const SkRect& drawBounds) {
46 #ifdef SK_DEBUG
47 if (programInfo.primProc().hasInstanceAttributes()) {
48 SkASSERT(this->gpu()->caps()->instanceAttribSupport());
49 }
50 if (programInfo.pipeline().usesConservativeRaster()) {
51 SkASSERT(this->gpu()->caps()->conservativeRasterSupport());
52 // Conservative raster, by default, only supports triangles. Implementations can
53 // optionally indicate that they also support points and lines, but we don't currently
54 // query or track that info.
55 SkASSERT(GrIsPrimTypeTris(programInfo.primitiveType()));
56 }
57 if (programInfo.pipeline().isWireframe()) {
58 SkASSERT(this->gpu()->caps()->wireframeSupport());
59 }
60 if (GrPrimitiveType::kPatches == programInfo.primitiveType()) {
61 SkASSERT(this->gpu()->caps()->shaderCaps()->tessellationSupport());
62 }
63 programInfo.checkAllInstantiated();
64 programInfo.checkMSAAAndMIPSAreResolved();
65 #endif
66
67 if (programInfo.primProc().numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
68 fDrawPipelineStatus = DrawPipelineStatus::kFailedToBind;
69 return;
70 }
71
72 if (!this->onBindPipeline(programInfo, drawBounds)) {
73 fDrawPipelineStatus = DrawPipelineStatus::kFailedToBind;
74 return;
75 }
76
77 #ifdef SK_DEBUG
78 GrProcessor::CustomFeatures processorFeatures = programInfo.requestedFeatures();
79 if (GrProcessor::CustomFeatures::kSampleLocations & processorFeatures) {
80 // Verify we always have the same sample pattern key, regardless of graphics state.
81 SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget)
82 == fRenderTarget->renderTargetPriv().getSamplePatternKey());
83 }
84 #endif
85
86 fDrawPipelineStatus = DrawPipelineStatus::kOk;
87 }
88
drawMeshes(const GrProgramInfo & programInfo,const GrMesh meshes[],int meshCount)89 void GrOpsRenderPass::drawMeshes(const GrProgramInfo& programInfo, const GrMesh meshes[],
90 int meshCount) {
91 if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
92 SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
93 this->gpu()->stats()->incNumFailedDraws();
94 return;
95 }
96
97 #ifdef SK_DEBUG
98 if (int numDynamicStateArrays = programInfo.numDynamicStateArrays()) {
99 SkASSERT(meshCount == numDynamicStateArrays);
100 }
101 for (int i = 0; i < meshCount; ++i) {
102 SkASSERT(programInfo.primProc().hasVertexAttributes() ==
103 SkToBool(meshes[i].vertexBuffer()));
104 SkASSERT(programInfo.primProc().hasInstanceAttributes() ==
105 SkToBool(meshes[i].instanceBuffer()));
106 if (GrPrimitiveRestart::kYes == meshes[i].primitiveRestart()) {
107 SkASSERT(this->gpu()->caps()->usePrimitiveRestart());
108 }
109 }
110 #endif
111
112 if (meshCount) {
113 this->onDrawMeshes(programInfo, meshes, meshCount);
114 }
115 }
116