Flutter Engine
The Flutter Engine
GrGLOpsRenderPass.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 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
9
13
14#ifdef SK_DEBUG
17#endif
18
19#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
20
21void GrGLOpsRenderPass::set(GrRenderTarget* rt, bool useMSAASurface, const SkIRect& contentBounds,
22 GrSurfaceOrigin origin, const LoadAndStoreInfo& colorInfo,
23 const StencilLoadAndStoreInfo& stencilInfo) {
24 SkASSERT(fGpu);
26 SkASSERT(fGpu == rt->getContext()->priv().getGpu());
27
28 this->INHERITED::set(rt, origin);
29 fUseMultisampleFBO = useMSAASurface;
30 fContentBounds = contentBounds;
31 fColorLoadAndStoreInfo = colorInfo;
32 fStencilLoadAndStoreInfo = stencilInfo;
33}
34
35GrNativeRect GrGLOpsRenderPass::dmsaaLoadStoreBounds() const {
37 // If frambeffer resolves have to be full size, then resolve the entire render target during
38 // load and store both, even if we will be doing so with a draw. We do this because we will
39 // have no other choice than to do a full size resolve at the end of the render pass, so the
40 // full DMSAA attachment needs to have valid content.
43 } else {
44 return GrNativeRect::MakeRelativeTo(fOrigin, fRenderTarget->height(), fContentBounds);
45 }
46}
47
48void GrGLOpsRenderPass::onBegin() {
49 auto glRT = static_cast<GrGLRenderTarget*>(fRenderTarget);
50 if (fUseMultisampleFBO &&
51 fColorLoadAndStoreInfo.fLoadOp == GrLoadOp::kLoad &&
52 glRT->hasDynamicMSAAAttachment()) {
53 // Load the single sample fbo into the dmsaa attachment.
54 if (fGpu->glCaps().canResolveSingleToMSAA()) {
55 fGpu->resolveRenderFBOs(glRT, this->dmsaaLoadStoreBounds().asSkIRect(),
57 } else {
58 fGpu->drawSingleIntoMSAAFBO(glRT, this->dmsaaLoadStoreBounds().asSkIRect());
59 }
60 }
61
62 fGpu->beginCommandBuffer(glRT, fUseMultisampleFBO, fContentBounds, fOrigin,
63 fColorLoadAndStoreInfo, fStencilLoadAndStoreInfo);
64}
65
66void GrGLOpsRenderPass::onEnd() {
67 auto glRT = static_cast<GrGLRenderTarget*>(fRenderTarget);
68 fGpu->endCommandBuffer(glRT, fUseMultisampleFBO, fColorLoadAndStoreInfo,
69 fStencilLoadAndStoreInfo);
70
71 if (fUseMultisampleFBO &&
72 fColorLoadAndStoreInfo.fStoreOp == GrStoreOp::kStore &&
73 glRT->hasDynamicMSAAAttachment()) {
74 // Blit the msaa attachment into the single sample fbo.
75 fGpu->resolveRenderFBOs(glRT, this->dmsaaLoadStoreBounds().asSkIRect(),
77 true /*invalidateReadBufferAfterBlit*/);
78 }
79}
80
81bool GrGLOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo,
82 const SkRect& drawBounds) {
83 fPrimitiveType = programInfo.primitiveType();
84 return fGpu->flushGLState(fRenderTarget, fUseMultisampleFBO, programInfo);
85}
86
87void GrGLOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
88 fGpu->flushScissorRect(scissor, fRenderTarget->height(), fOrigin);
89}
90
91bool GrGLOpsRenderPass::onBindTextures(const GrGeometryProcessor& geomProc,
92 const GrSurfaceProxy* const geomProcTextures[],
93 const GrPipeline& pipeline) {
94 GrGLProgram* program = fGpu->currentProgram();
95 SkASSERT(program);
96 program->bindTextures(geomProc, geomProcTextures, pipeline);
97 return true;
98}
99
100void GrGLOpsRenderPass::onBindBuffers(sk_sp<const GrBuffer> indexBuffer,
101 sk_sp<const GrBuffer> instanceBuffer,
102 sk_sp<const GrBuffer> vertexBuffer,
103 GrPrimitiveRestart primitiveRestart) {
104 SkASSERT((primitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer);
105 GrGLProgram* program = fGpu->currentProgram();
106 SkASSERT(program);
107
108#ifdef SK_DEBUG
109 fDidBindInstanceBuffer = false;
110 fDidBindVertexBuffer = false;
111#endif
112
113 int numAttribs = program->numVertexAttributes() + program->numInstanceAttributes();
114 fAttribArrayState = fGpu->bindInternalVertexArray(indexBuffer.get(), numAttribs,
115 primitiveRestart);
116
117 if (indexBuffer) {
118 if (indexBuffer->isCpuBuffer()) {
119 auto* cpuIndexBuffer = static_cast<const GrCpuBuffer*>(indexBuffer.get());
120 fIndexPointer = reinterpret_cast<const uint16_t*>(cpuIndexBuffer->data());
121 } else {
122 fIndexPointer = nullptr;
123 }
124 }
125
126 // If this platform does not support baseInstance, defer binding of the instance buffer.
128 this->bindInstanceBuffer(instanceBuffer.get(), 0);
129 SkDEBUGCODE(fDidBindInstanceBuffer = true;)
130 }
131 fActiveInstanceBuffer = std::move(instanceBuffer);
132
133 // We differ binding the vertex buffer for one of two situations:
134 // 1) This platform does not support baseVertex with indexed draws.
135 // 2) There is a driver bug affecting glDrawArrays.
136 if ((indexBuffer && fGpu->glCaps().baseVertexBaseInstanceSupport()) ||
137 (!indexBuffer && !fGpu->glCaps().drawArraysBaseVertexIsBroken())) {
138 this->bindVertexBuffer(vertexBuffer.get(), 0);
139 SkDEBUGCODE(fDidBindVertexBuffer = true;)
140 }
141 fActiveVertexBuffer = std::move(vertexBuffer);
142 fActiveIndexBuffer = std::move(indexBuffer);
143}
144
145void GrGLOpsRenderPass::bindInstanceBuffer(const GrBuffer* instanceBuffer, int baseInstance) {
146 GrGLProgram* program = fGpu->currentProgram();
147 SkASSERT(program);
148 if (int instanceStride = program->instanceStride()) {
149 SkASSERT(instanceBuffer);
150 SkASSERT(instanceBuffer->isCpuBuffer() ||
151 !static_cast<const GrGpuBuffer*>(instanceBuffer)->isMapped());
152 size_t bufferOffset = baseInstance * static_cast<size_t>(instanceStride);
153 int attribIdx = program->numVertexAttributes();
154 for (int i = 0; i < program->numInstanceAttributes(); ++i, ++attribIdx) {
155 const auto& attrib = program->instanceAttribute(i);
156 static constexpr int kDivisor = 1;
157 fAttribArrayState->set(fGpu, attrib.fLocation, instanceBuffer, attrib.fCPUType,
158 attrib.fGPUType, instanceStride, bufferOffset + attrib.fOffset,
159 kDivisor);
160 }
161 }
162}
163
164void GrGLOpsRenderPass::bindVertexBuffer(const GrBuffer* vertexBuffer, int baseVertex) {
165 GrGLProgram* program = fGpu->currentProgram();
166 SkASSERT(program);
167 if (int vertexStride = program->vertexStride()) {
168 SkASSERT(vertexBuffer);
169 SkASSERT(vertexBuffer->isCpuBuffer() ||
170 !static_cast<const GrGpuBuffer*>(vertexBuffer)->isMapped());
171 size_t bufferOffset = baseVertex * static_cast<size_t>(vertexStride);
172 for (int i = 0; i < program->numVertexAttributes(); ++i) {
173 const auto& attrib = program->vertexAttribute(i);
174 static constexpr int kDivisor = 0;
175 fAttribArrayState->set(fGpu, attrib.fLocation, vertexBuffer, attrib.fCPUType,
176 attrib.fGPUType, vertexStride, bufferOffset + attrib.fOffset,
177 kDivisor);
178 }
179 }
180}
181
182void GrGLOpsRenderPass::onDraw(int vertexCount, int baseVertex) {
183 SkASSERT(fDidBindVertexBuffer || fGpu->glCaps().drawArraysBaseVertexIsBroken());
184 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
185 if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
186 this->bindVertexBuffer(fActiveVertexBuffer.get(), baseVertex);
187 baseVertex = 0;
188 }
189 GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount));
191}
192
193void GrGLOpsRenderPass::onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
194 uint16_t maxIndexValue, int baseVertex) {
195 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
198 SkASSERT(fDidBindVertexBuffer);
199 if (baseVertex != 0) {
200 GL_CALL(DrawElementsInstancedBaseVertexBaseInstance(
201 glPrimType, indexCount, GR_GL_UNSIGNED_SHORT,
202 this->offsetForBaseIndex(baseIndex), 1, baseVertex, 0));
203 return;
204 }
205 } else {
206 this->bindVertexBuffer(fActiveVertexBuffer.get(), baseVertex);
207 }
208
209 if (fGpu->glCaps().drawRangeElementsSupport()) {
210 GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount,
211 GR_GL_UNSIGNED_SHORT, this->offsetForBaseIndex(baseIndex)));
212 } else {
213 GL_CALL(DrawElements(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT,
214 this->offsetForBaseIndex(baseIndex)));
215 }
217}
218
219void GrGLOpsRenderPass::onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
220 int baseVertex) {
221 SkASSERT(fDidBindVertexBuffer || fGpu->glCaps().drawArraysBaseVertexIsBroken());
222 if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
223 // We weren't able to bind the vertex buffer during onBindBuffers because of a driver bug
224 // affecting glDrawArrays.
225 this->bindVertexBuffer(fActiveVertexBuffer.get(), 0);
226 }
227 int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
228 for (int i = 0; i < instanceCount; i += maxInstances) {
229 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
230 int instanceCountForDraw = std::min(instanceCount - i, maxInstances);
231 int baseInstanceForDraw = baseInstance + i;
233 SkASSERT(fDidBindInstanceBuffer);
234 GL_CALL(DrawArraysInstancedBaseInstance(glPrimType, baseVertex, vertexCount,
235 instanceCountForDraw, baseInstanceForDraw));
236 } else {
237 this->bindInstanceBuffer(fActiveInstanceBuffer.get(), baseInstanceForDraw);
238 GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, instanceCountForDraw));
239 }
240 }
242}
243
244void GrGLOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
245 int baseInstance, int baseVertex) {
246 int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
247 for (int i = 0; i < instanceCount; i += maxInstances) {
248 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
249 int instanceCountForDraw = std::min(instanceCount - i, maxInstances);
250 int baseInstanceForDraw = baseInstance + i;
252 SkASSERT(fDidBindInstanceBuffer);
253 SkASSERT(fDidBindVertexBuffer);
254 GL_CALL(DrawElementsInstancedBaseVertexBaseInstance(
255 glPrimType, indexCount, GR_GL_UNSIGNED_SHORT,
256 this->offsetForBaseIndex(baseIndex), instanceCountForDraw, baseVertex,
257 baseInstanceForDraw));
258 } else {
259 this->bindInstanceBuffer(fActiveInstanceBuffer.get(), baseInstanceForDraw);
260 this->bindVertexBuffer(fActiveVertexBuffer.get(), baseVertex);
261 GL_CALL(DrawElementsInstanced(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT,
262 this->offsetForBaseIndex(baseIndex), instanceCountForDraw));
263 }
264 }
266}
267
268static const void* buffer_offset_to_gl_address(const GrBuffer* drawIndirectBuffer, size_t offset) {
269 if (drawIndirectBuffer->isCpuBuffer()) {
270 return static_cast<const GrCpuBuffer*>(drawIndirectBuffer)->data() + offset;
271 } else {
272 return (offset) ? reinterpret_cast<const void*>(offset) : nullptr;
273 }
274}
275
276void GrGLOpsRenderPass::onDrawIndirect(const GrBuffer* drawIndirectBuffer, size_t offset,
277 int drawCount) {
278 using MultiDrawType = GrGLCaps::MultiDrawType;
279
282 SkASSERT(fDidBindVertexBuffer || fGpu->glCaps().drawArraysBaseVertexIsBroken());
283
284 if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
285 // We weren't able to bind the vertex buffer during onBindBuffers because of a driver bug
286 // affecting glDrawArrays.
287 this->bindVertexBuffer(fActiveVertexBuffer.get(), 0);
288 }
289
290 if (fGpu->glCaps().multiDrawType() == MultiDrawType::kANGLEOrWebGL) {
291 // ANGLE and WebGL don't support glDrawElementsIndirect. We draw everything as a multi draw.
292 this->multiDrawArraysANGLEOrWebGL(drawIndirectBuffer, offset, drawCount);
293 return;
294 }
295
296 fGpu->bindBuffer(GrGpuBufferType::kDrawIndirect, drawIndirectBuffer);
297
298 if (drawCount > 1 && fGpu->glCaps().multiDrawType() == MultiDrawType::kMultiDrawIndirect) {
299 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
300 GL_CALL(MultiDrawArraysIndirect(glPrimType,
301 buffer_offset_to_gl_address(drawIndirectBuffer, offset),
302 drawCount, sizeof(GrDrawIndirectCommand)));
303 return;
304 }
305
306 for (int i = 0; i < drawCount; ++i) {
307 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
308 GL_CALL(DrawArraysIndirect(glPrimType,
309 buffer_offset_to_gl_address(drawIndirectBuffer, offset)));
310 offset += sizeof(GrDrawIndirectCommand);
311 }
313}
314
315void GrGLOpsRenderPass::multiDrawArraysANGLEOrWebGL(const GrBuffer* drawIndirectBuffer,
316 size_t offset, int drawCount) {
318 SkASSERT(drawIndirectBuffer->isCpuBuffer());
319
320 constexpr static int kMaxDrawCountPerBatch = 128;
321 GrGLint fFirsts[kMaxDrawCountPerBatch];
322 GrGLsizei fCounts[kMaxDrawCountPerBatch];
323 GrGLsizei fInstanceCounts[kMaxDrawCountPerBatch];
324 GrGLuint fBaseInstances[kMaxDrawCountPerBatch];
325
326 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
327 auto* cpuBuffer = static_cast<const GrCpuBuffer*>(drawIndirectBuffer);
328 auto* cmds = reinterpret_cast<const GrDrawIndirectCommand*>(cpuBuffer->data() + offset);
329
330 while (drawCount) {
331 int countInBatch = std::min(drawCount, kMaxDrawCountPerBatch);
332 for (int i = 0; i < countInBatch; ++i) {
333 auto [vertexCount, instanceCount, baseVertex, baseInstance] = cmds[i];
334 fFirsts[i] = baseVertex;
335 fCounts[i] = vertexCount;
336 fInstanceCounts[i] = instanceCount;
337 fBaseInstances[i] = baseInstance;
338 }
339 if (countInBatch == 1) {
340 GL_CALL(DrawArraysInstancedBaseInstance(glPrimType, fFirsts[0], fCounts[0],
341 fInstanceCounts[0], fBaseInstances[0]));
342 } else {
343 GL_CALL(MultiDrawArraysInstancedBaseInstance(glPrimType, fFirsts, fCounts,
344 fInstanceCounts, fBaseInstances,
345 countInBatch));
346 }
347 drawCount -= countInBatch;
348 cmds += countInBatch;
349 }
351}
352
353void GrGLOpsRenderPass::onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t offset,
354 int drawCount) {
355 using MultiDrawType = GrGLCaps::MultiDrawType;
356
360 // The vertex buffer should have already gotten bound (as opposed us stashing it away during
361 // onBindBuffers and not expecting to bind it until this point).
362 SkASSERT(fDidBindVertexBuffer);
363
364 if (fGpu->glCaps().multiDrawType() == MultiDrawType::kANGLEOrWebGL) {
365 // ANGLE and WebGL don't support glDrawElementsIndirect. We draw everything as a multi draw.
366 this->multiDrawElementsANGLEOrWebGL(drawIndirectBuffer, offset, drawCount);
367 return;
368 }
369
370 fGpu->bindBuffer(GrGpuBufferType::kDrawIndirect, drawIndirectBuffer);
371
372 if (drawCount > 1 && fGpu->glCaps().multiDrawType() == MultiDrawType::kMultiDrawIndirect) {
373 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
374 GL_CALL(MultiDrawElementsIndirect(glPrimType, GR_GL_UNSIGNED_SHORT,
375 buffer_offset_to_gl_address(drawIndirectBuffer, offset),
376 drawCount, sizeof(GrDrawIndexedIndirectCommand)));
377 return;
378 }
379
380 for (int i = 0; i < drawCount; ++i) {
381 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
382 GL_CALL(DrawElementsIndirect(glPrimType, GR_GL_UNSIGNED_SHORT,
383 buffer_offset_to_gl_address(drawIndirectBuffer, offset)));
385 }
387}
388
389void GrGLOpsRenderPass::multiDrawElementsANGLEOrWebGL(const GrBuffer* drawIndirectBuffer,
390 size_t offset, int drawCount) {
392 SkASSERT(drawIndirectBuffer->isCpuBuffer());
393
394 constexpr static int kMaxDrawCountPerBatch = 128;
395 GrGLint fCounts[kMaxDrawCountPerBatch];
396 const void* fIndices[kMaxDrawCountPerBatch];
397 GrGLsizei fInstanceCounts[kMaxDrawCountPerBatch];
398 GrGLint fBaseVertices[kMaxDrawCountPerBatch];
399 GrGLuint fBaseInstances[kMaxDrawCountPerBatch];
400
401 GrGLenum glPrimType = fGpu->prepareToDraw(fPrimitiveType);
402 auto* cpuBuffer = static_cast<const GrCpuBuffer*>(drawIndirectBuffer);
403 auto* cmds = reinterpret_cast<const GrDrawIndexedIndirectCommand*>(cpuBuffer->data() + offset);
404
405 while (drawCount) {
406 int countInBatch = std::min(drawCount, kMaxDrawCountPerBatch);
407 for (int i = 0; i < countInBatch; ++i) {
408 auto [indexCount, instanceCount, baseIndex, baseVertex, baseInstance] = cmds[i];
409 fCounts[i] = indexCount;
410 fIndices[i] = this->offsetForBaseIndex(baseIndex);
411 fInstanceCounts[i] = instanceCount;
412 fBaseVertices[i] = baseVertex;
413 fBaseInstances[i] = baseInstance;
414 }
415 if (countInBatch == 1) {
416 GL_CALL(DrawElementsInstancedBaseVertexBaseInstance(glPrimType, fCounts[0],
417 GR_GL_UNSIGNED_SHORT, fIndices[0],
418 fInstanceCounts[0],
419 fBaseVertices[0],
420 fBaseInstances[0]));
421 } else {
422 GL_CALL(MultiDrawElementsInstancedBaseVertexBaseInstance(glPrimType, fCounts,
423 GR_GL_UNSIGNED_SHORT, fIndices,
424 fInstanceCounts, fBaseVertices,
425 fBaseInstances, countInBatch));
426 }
427 drawCount -= countInBatch;
428 cmds += countInBatch;
429 }
431}
432
433void GrGLOpsRenderPass::onClear(const GrScissorState& scissor, std::array<float, 4> color) {
434 fGpu->clear(scissor, color, fRenderTarget, fUseMultisampleFBO, fOrigin);
435}
436
437void GrGLOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) {
438 fGpu->clearStencilClip(scissor, insideStencilMask, fRenderTarget, fUseMultisampleFBO, fOrigin);
439}
#define GR_GL_UNSIGNED_SHORT
Definition: GrGLDefines.h:352
static const void * buffer_offset_to_gl_address(const GrBuffer *drawIndirectBuffer, size_t offset)
#define GL_CALL(X)
unsigned int GrGLuint
Definition: GrGLTypes.h:113
int GrGLsizei
Definition: GrGLTypes.h:109
int GrGLint
Definition: GrGLTypes.h:108
unsigned int GrGLenum
Definition: GrGLTypes.h:102
GrPrimitiveRestart
Definition: GrTypesPriv.h:56
GrSurfaceOrigin
Definition: GrTypes.h:147
#define SkASSERT(cond)
Definition: SkAssert.h:116
virtual bool isCpuBuffer() const =0
bool nativeDrawIndirectSupport() const
Definition: GrCaps.h:84
bool nativeDrawIndexedIndirectIsBroken() const
Definition: GrCaps.h:144
bool drawInstancedSupport() const
Definition: GrCaps.h:80
GrDirectContextPriv priv()
void set(GrGLGpu *, int attribIndex, const GrBuffer *vertexBuffer, GrVertexAttribType cpuType, SkSLType gpuType, GrGLsizei stride, size_t offsetInBytes, int divisor=0)
bool drawRangeElementsSupport() const
Is there support for glDrawRangeElements?
Definition: GrGLCaps.h:365
bool baseVertexBaseInstanceSupport() const
Are the glDraw*Base(VertexBase)Instance methods, and baseInstance fields in indirect draw.
Definition: GrGLCaps.h:369
int maxInstancesPerDrawWithoutCrashing(int pendingInstanceCount) const
Definition: GrGLCaps.h:468
bool drawArraysBaseVertexIsBroken() const
Definition: GrGLCaps.h:407
MultiDrawType
Definition: GrGLCaps.h:126
MultiDrawType multiDrawType() const
How are multi draws implemented (if at all)?
Definition: GrGLCaps.h:338
bool framebufferResolvesMustBeFullSize() const
Definition: GrGLCaps.h:299
bool canResolveSingleToMSAA() const
Definition: GrGLCaps.h:308
void flushScissorRect(const SkIRect &scissor, int rtHeight, GrSurfaceOrigin)
Definition: GrGLGpu.cpp:2016
const GrGLCaps & glCaps() const
Definition: GrGLGpu.h:108
void clear(const GrScissorState &, std::array< float, 4 > color, GrRenderTarget *, bool useMultisampleFBO, GrSurfaceOrigin)
Definition: GrGLGpu.cpp:2180
void clearStencilClip(const GrScissorState &, bool insideStencilMask, GrRenderTarget *, bool useMultisampleFBO, GrSurfaceOrigin)
Definition: GrGLGpu.cpp:2302
GrGLProgram * currentProgram()
Definition: GrGLGpu.h:144
GrGLenum prepareToDraw(GrPrimitiveType primitiveType)
Definition: GrGLGpu.cpp:2527
void didDrawTo(GrRenderTarget *)
Definition: GrGLGpu.cpp:2145
GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer *)
Definition: GrGLGpu.cpp:2154
void resolveRenderFBOs(GrGLRenderTarget *, const SkIRect &resolveRect, ResolveDirection, bool invalidateReadBufferAfterBlit=false)
Definition: GrGLGpu.cpp:2562
void beginCommandBuffer(GrGLRenderTarget *, bool useMultisampleFBO, const SkIRect &bounds, GrSurfaceOrigin, const GrOpsRenderPass::LoadAndStoreInfo &colorLoadStore, const GrOpsRenderPass::StencilLoadAndStoreInfo &stencilLoadStore)
Definition: GrGLGpu.cpp:2211
bool flushGLState(GrRenderTarget *, bool useMultisampleFBO, const GrProgramInfo &)
Definition: GrGLGpu.cpp:2076
void drawSingleIntoMSAAFBO(GrGLRenderTarget *rt, const SkIRect &drawBounds)
Definition: GrGLGpu.h:179
void endCommandBuffer(GrGLRenderTarget *, bool useMultisampleFBO, const GrOpsRenderPass::LoadAndStoreInfo &colorLoadStore, const GrOpsRenderPass::StencilLoadAndStoreInfo &stencilLoadStore)
Definition: GrGLGpu.cpp:2254
GrGLAttribArrayState * bindInternalVertexArray(const GrBuffer *indexBuffer, int numAttribs, GrPrimitiveRestart primitiveRestart)
Definition: GrGLGpu.h:156
void set(GrRenderTarget *, bool useMSAASurface, const SkIRect &contentBounds, GrSurfaceOrigin, const LoadAndStoreInfo &, const StencilLoadAndStoreInfo &)
int numVertexAttributes() const
Definition: GrGLProgram.h:114
int instanceStride() const
Definition: GrGLProgram.h:112
const Attribute & vertexAttribute(int i) const
Definition: GrGLProgram.h:115
int vertexStride() const
Definition: GrGLProgram.h:111
void bindTextures(const GrGeometryProcessor &, const GrSurfaceProxy *const geomProcTextures[], const GrPipeline &)
int numInstanceAttributes() const
Definition: GrGLProgram.h:120
const Attribute & instanceAttribute(int i) const
Definition: GrGLProgram.h:121
bool isMapped() const
Definition: GrGpuBuffer.cpp:47
const GrDirectContext * getContext() const
const GrCaps * caps() const
Definition: GrGpu.h:73
sk_sp< const GrBuffer > fActiveIndexBuffer
sk_sp< const GrBuffer > fActiveInstanceBuffer
sk_sp< const GrBuffer > fActiveVertexBuffer
void set(GrRenderTarget *rt, GrSurfaceOrigin origin)
GrSurfaceOrigin fOrigin
GrRenderTarget * fRenderTarget
GrPrimitiveType primitiveType() const
Definition: GrProgramInfo.h:42
SkISize dimensions() const
Definition: GrSurface.h:27
int height() const
Definition: GrSurface.h:37
T * get() const
Definition: SkRefCnt.h:303
DlColor color
static float min(float r, float g, float b)
Definition: hsl.cpp:48
SeparatedVector2 offset
SkIRect asSkIRect() const
Definition: GrNativeRect.h:49
static GrNativeRect MakeRelativeTo(GrSurfaceOrigin origin, int rtHeight, SkIRect devRect)
Definition: GrNativeRect.h:25
Definition: SkRect.h:32
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63