1/*
2 * Copyright 2011 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 GrGLGpu_DEFINED
9#define GrGLGpu_DEFINED
10
11#include "include/core/SkTypes.h"
12#include "include/private/SkTArray.h"
13#include "src/core/SkLRUCache.h"
14#include "src/gpu/GrFinishCallbacks.h"
15#include "src/gpu/GrGpu.h"
16#include "src/gpu/GrNativeRect.h"
17#include "src/gpu/GrProgramDesc.h"
18#include "src/gpu/GrWindowRectsState.h"
19#include "src/gpu/GrXferProcessor.h"
20#include "src/gpu/gl/GrGLContext.h"
21#include "src/gpu/gl/GrGLPathRendering.h"
22#include "src/gpu/gl/GrGLProgram.h"
23#include "src/gpu/gl/GrGLRenderTarget.h"
24#include "src/gpu/gl/GrGLStencilAttachment.h"
25#include "src/gpu/gl/GrGLTexture.h"
26#include "src/gpu/gl/GrGLVertexArray.h"
27
28class GrGLBuffer;
29class GrGLOpsRenderPass;
30class GrPipeline;
31class GrSwizzle;
32
33class GrGLGpu final : public GrGpu {
34public:
35 static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrDirectContext*);
36 ~GrGLGpu() override;
37
38 void disconnect(DisconnectType) override;
39
40 const GrGLContext& glContext() const { return *fGLContext; }
41
42 const GrGLInterface* glInterface() const { return fGLContext->glInterface(); }
43 const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
44 GrGLStandard glStandard() const { return fGLContext->standard(); }
45 GrGLVersion glVersion() const { return fGLContext->version(); }
46 GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
47 const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
48
49 GrGLPathRendering* glPathRendering() {
50 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
51 return static_cast<GrGLPathRendering*>(pathRendering());
52 }
53
54 // Used by GrGLProgram to configure OpenGL state.
55 void bindTexture(int unitIdx, GrSamplerState samplerState, const GrSwizzle&, GrGLTexture*);
56
57 // These functions should be used to bind GL objects. They track the GL state and skip redundant
58 // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
59 void bindVertexArray(GrGLuint id) {
60 fHWVertexArrayState.setVertexArrayID(this, id);
61 }
62
63 // These callbacks update state tracking when GL objects are deleted. They are called from
64 // GrGLResource onRelease functions.
65 void notifyVertexArrayDelete(GrGLuint id) {
66 fHWVertexArrayState.notifyVertexArrayDelete(id);
67 }
68
69 // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
70 // returns the GL target the buffer was bound to.
71 // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
72 // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
73 GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*);
74
75 // Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set.
76 bool flushGLState(GrRenderTarget*, const GrProgramInfo&);
77 void flushScissorRect(const SkIRect&, int rtWidth, int rtHeight, GrSurfaceOrigin);
78
79 // Returns the last program bound by flushGLState(), or nullptr if a different program has since
80 // been put into use via some other method (e.g., resetContext, copySurfaceAsDraw).
81 // The returned GrGLProgram can be used for binding textures and vertex attributes.
82 GrGLProgram* currentProgram() {
83 this->handleDirtyContext();
84 return fHWProgram.get();
85 }
86
87 // Binds the vertex array that should be used for internal draws, enables 'numAttribs' vertex
88 // arrays, and flushes the desired primitive restart settings. If an index buffer is provided,
89 // it will be bound to the vertex array. Otherwise the index buffer binding will be left
90 // unchanged.
91 //
92 // NOTE: This binds the default VAO (ID=zero) unless we are on a core profile, in which case we
93 // use a dummy array instead.
94 GrGLAttribArrayState* bindInternalVertexArray(const GrBuffer* indexBuffer, int numAttribs,
95 GrPrimitiveRestart primitiveRestart) {
96 auto* attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
97 attribState->enableVertexArrays(this, numAttribs, primitiveRestart);
98 return attribState;
99 }
100
101 // Applies any necessary workarounds and returns the GL primitive type to use in draw calls.
102 GrGLenum prepareToDraw(GrPrimitiveType primitiveType);
103
104 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
105 // Thus this is the implementation of the clear call for the corresponding passthrough function
106 // on GrGLOpsRenderPass.
107 void clear(const GrScissorState&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin);
108
109 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
110 // Thus this is the implementation of the clearStencil call for the corresponding passthrough
111 // function on GrGLOpsrenderPass.
112 void clearStencilClip(const GrScissorState&, bool insideStencilMask,
113 GrRenderTarget*, GrSurfaceOrigin);
114
115 void beginCommandBuffer(GrRenderTarget*, const SkIRect& bounds, GrSurfaceOrigin,
116 const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
117 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
118
119 void endCommandBuffer(GrRenderTarget*, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
120 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
121
122 GrOpsRenderPass* getOpsRenderPass(
123 GrRenderTarget*, GrStencilAttachment*,
124 GrSurfaceOrigin, const SkIRect&,
125 const GrOpsRenderPass::LoadAndStoreInfo&,
126 const GrOpsRenderPass::StencilLoadAndStoreInfo&,
127 const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override;
128
129 void invalidateBoundRenderTarget() {
130 fHWBoundRenderTargetUniqueID.makeInvalid();
131 }
132
133 GrStencilAttachment* createStencilAttachmentForRenderTarget(
134 const GrRenderTarget* rt, int width, int height, int numStencilSamples) override;
135 void deleteBackendTexture(const GrBackendTexture&) override;
136
137 bool compile(const GrProgramDesc&, const GrProgramInfo&) override;
138
139 bool precompileShader(const SkData& key, const SkData& data) override {
140 return fProgramCache->precompileShader(key, data);
141 }
142
143#if GR_TEST_UTILS
144 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
145
146 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
147 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
148
149 const GrGLContext* glContextForTesting() const override { return &this->glContext(); }
150
151 void resetShaderCacheForTesting() const override { fProgramCache->reset(); }
152
153 void testingOnly_flushGpuAndSync() override;
154#endif
155
156 void submit(GrOpsRenderPass* renderPass) override;
157
158 GrFence SK_WARN_UNUSED_RESULT insertFence() override;
159 bool waitFence(GrFence) override;
160 void deleteFence(GrFence) const override;
161
162 std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
163 std::unique_ptr<GrSemaphore> wrapBackendSemaphore(
164 const GrBackendSemaphore& semaphore,
165 GrResourceProvider::SemaphoreWrapType wrapType,
166 GrWrapOwnership ownership) override;
167 void insertSemaphore(GrSemaphore* semaphore) override;
168 void waitSemaphore(GrSemaphore* semaphore) override;
169
170 void checkFinishProcs() override;
171
172 // Calls glGetError() until no errors are reported. Also looks for OOMs.
173 void clearErrorsAndCheckForOOM();
174 // Calls glGetError() once and returns the result. Also looks for an OOM.
175 GrGLenum getErrorAndCheckForOOM();
176
177 std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
178
179 void deleteSync(GrGLsync) const;
180
181 void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid);
182 void deleteFramebuffer(GrGLuint fboid);
183
184 void insertManualFramebufferBarrier() override;
185
186 void flushProgram(sk_sp<GrGLProgram>);
187
188 // Version for programs that aren't GrGLProgram.
189 void flushProgram(GrGLuint);
190
191private:
192 GrGLGpu(std::unique_ptr<GrGLContext>, GrDirectContext*);
193
194 // GrGpu overrides
195 GrBackendTexture onCreateBackendTexture(SkISize dimensions,
196 const GrBackendFormat&,
197 GrRenderable,
198 GrMipmapped,
199 GrProtected) override;
200
201 GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
202 const GrBackendFormat&,
203 GrMipmapped,
204 GrProtected) override;
205
206 bool onUpdateBackendTexture(const GrBackendTexture&,
207 sk_sp<GrRefCntedCallback> finishedCallback,
208 const BackendTextureData*) override;
209
210 bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
211 sk_sp<GrRefCntedCallback> finishedCallback,
212 const BackendTextureData*) override;
213
214 void onResetContext(uint32_t resetBits) override;
215
216 void onResetTextureBindings() override;
217
218 void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) override;
219
220 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
221
222 sk_sp<GrTexture> onCreateTexture(SkISize dimensions,
223 const GrBackendFormat&,
224 GrRenderable,
225 int renderTargetSampleCnt,
226 SkBudgeted,
227 GrProtected,
228 int mipLevelCount,
229 uint32_t levelClearMask) override;
230 sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
231 const GrBackendFormat&,
232 SkBudgeted,
233 GrMipmapped,
234 GrProtected,
235 const void* data, size_t dataSize) override;
236
237 sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern,
238 const void* data) override;
239
240 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
241 GrWrapOwnership,
242 GrWrapCacheable,
243 GrIOType) override;
244 sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
245 GrWrapOwnership,
246 GrWrapCacheable) override;
247 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
248 int sampleCnt,
249 GrWrapOwnership,
250 GrWrapCacheable) override;
251 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
252 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
253 int sampleCnt) override;
254
255 // Given a GL format return the index into the stencil format array on GrGLCaps to a
256 // compatible stencil format, or negative if there is no compatible stencil format.
257 int getCompatibleStencilIndex(GrGLFormat format);
258
259 void onFBOChanged();
260
261 // Returns whether the texture is successfully created. On success, a non-zero texture ID is
262 // returned. On failure, zero is returned.
263 // The texture is populated with |texels|, if it is non-null.
264 // The texture parameters are cached in |initialTexParams|.
265 GrGLuint createTexture(SkISize dimensions,
266 GrGLFormat,
267 GrGLenum target,
268 GrRenderable,
269 GrGLTextureParameters::SamplerOverriddenState*,
270 int mipLevelCount);
271
272 GrGLuint createCompressedTexture2D(SkISize dimensions,
273 SkImage::CompressionType compression,
274 GrGLFormat,
275 GrMipmapped,
276 GrGLTextureParameters::SamplerOverriddenState*);
277
278 bool onReadPixels(GrSurface*, int left, int top, int width, int height,
279 GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
280 size_t rowBytes) override;
281
282 bool onWritePixels(GrSurface*, int left, int top, int width, int height,
283 GrColorType surfaceColorType, GrColorType srcColorType,
284 const GrMipLevel texels[], int mipLevelCount,
285 bool prepForTexSampling) override;
286
287 bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
288 GrColorType textureColorType, GrColorType bufferColorType,
289 GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes) override;
290 bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
291 GrColorType surfaceColorType, GrColorType bufferColorType,
292 GrGpuBuffer* transferBuffer, size_t offset) override;
293 bool readOrTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
294 GrColorType surfaceColorType, GrColorType dstColorType,
295 void* offsetOrPtr, int rowWidthInPixels);
296
297 // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the
298 // PIXEL_UNPACK_BUFFER is unbound.
299 void unbindCpuToGpuXferBuffer();
300
301 void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override;
302
303 bool onRegenerateMipMapLevels(GrTexture*) override;
304
305 bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
306 const SkIPoint& dstPoint) override;
307
308 // binds texture unit in GL
309 void setTextureUnit(int unitIdx);
310
311 void flushBlendAndColorWrite(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
312
313 void addFinishedProc(GrGpuFinishedProc finishedProc,
314 GrGpuFinishedContext finishedContext) override;
315
316 bool onSubmitToGpu(bool syncCpu) override;
317
318 bool waitSync(GrGLsync, uint64_t timeout, bool flush);
319
320 bool copySurfaceAsDraw(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
321 const SkIPoint& dstPoint);
322 void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
323 const SkIPoint& dstPoint);
324 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
325 const SkIPoint& dstPoint);
326
327 class ProgramCache : public ::SkNoncopyable {
328 public:
329 ProgramCache(GrGLGpu* gpu);
330 ~ProgramCache();
331
332 void abandon();
333 void reset();
334 sk_sp<GrGLProgram> findOrCreateProgram(GrRenderTarget*, const GrProgramInfo&);
335 sk_sp<GrGLProgram> findOrCreateProgram(const GrProgramDesc& desc,
336 const GrProgramInfo& programInfo,
337 Stats::ProgramCacheResult* stat) {
338 sk_sp<GrGLProgram> tmp = this->findOrCreateProgram(nullptr, desc, programInfo, stat);
339 if (!tmp) {
340 fGpu->fStats.incNumPreCompilationFailures();
341 } else {
342 fGpu->fStats.incNumPreProgramCacheResult(*stat);
343 }
344
345 return tmp;
346 }
347 bool precompileShader(const SkData& key, const SkData& data);
348
349 private:
350 struct Entry;
351
352 sk_sp<GrGLProgram> findOrCreateProgram(GrRenderTarget*,
353 const GrProgramDesc&,
354 const GrProgramInfo&,
355 Stats::ProgramCacheResult*);
356
357 struct DescHash {
358 uint32_t operator()(const GrProgramDesc& desc) const {
359 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
360 }
361 };
362
363 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
364
365 GrGLGpu* fGpu;
366 };
367
368 void flushPatchVertexCount(uint8_t count);
369
370 void flushColorWrite(bool writeColor);
371 void flushClearColor(const SkPMColor4f&);
372
373 // flushes the scissor. see the note on flushBoundTextureAndParams about
374 // flushing the scissor after that function is called.
375 void flushScissor(const GrScissorState& scissorState, int rtWidth, int rtHeight,
376 GrSurfaceOrigin rtOrigin) {
377 this->flushScissorTest(GrScissorTest(scissorState.enabled()));
378 if (scissorState.enabled()) {
379 this->flushScissorRect(scissorState.rect(), rtWidth, rtHeight, rtOrigin);
380 }
381 }
382 void flushScissorTest(GrScissorTest);
383
384 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
385 void disableWindowRectangles();
386
387 int numTextureUnits() const { return this->caps()->shaderCaps()->maxFragmentSamplers(); }
388
389 // Binds a texture to a target on the "scratch" texture unit to use for texture operations
390 // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw). It
391 // ensures that such operations don't negatively interact with draws. The active texture unit
392 // and the binding for 'target' will change.
393 void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID);
394
395 // The passed bounds contains the render target's color values that will subsequently be
396 // written.
397 void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds);
398 // This version has an implicit bounds of the entire render target.
399 void flushRenderTarget(GrGLRenderTarget*);
400 // This version can be used when the render target's colors will not be written.
401 void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
402
403 // Need not be called if flushRenderTarget is used.
404 void flushViewport(int width, int height);
405
406 void flushStencil(const GrStencilSettings&, GrSurfaceOrigin);
407 void disableStencil();
408
409 // rt is used only if useHWAA is true.
410 void flushHWAAState(GrRenderTarget* rt, bool useHWAA);
411
412 void flushConservativeRasterState(bool enable);
413
414 void flushWireframeState(bool enable);
415
416 void flushFramebufferSRGB(bool enable);
417
418 // Uploads src data of a color type to the currently bound texture on the active texture unit.
419 // The caller specifies color type that the texture is being used with, which may be different
420 // than the src color type. This fails if the combination of texture format, texture color type,
421 // and src data color type are not valid. No conversion is performed on the data before passing
422 // it to GL. 'dstRect' must be the texture bounds if mipLevelCount is greater than 1.
423 bool uploadColorTypeTexData(GrGLFormat textureFormat,
424 GrColorType textureColorType,
425 SkISize texDims,
426 GrGLenum target,
427 SkIRect dstRect,
428 GrColorType srcColorType,
429 const GrMipLevel texels[],
430 int mipLevelCount);
431
432 // Uploads a constant color to a texture using the "default" format and color type. Overwrites
433 // entire levels. Bit n in 'levelMask' indicates whether level n should be written. This
434 // function doesn't know if MIP levels have been allocated, thus levelMask should not have bits
435 // beyond the low bit set if the texture is not MIP mapped.
436 bool uploadColorToTex(GrGLFormat textureFormat,
437 SkISize texDims,
438 GrGLenum target,
439 SkColor4f color,
440 uint32_t levelMask);
441
442 // Pushes data to the currently bound texture to the currently active unit. 'dstRect' must be
443 // the texture bounds if mipLevelCount is greater than 1.
444 void uploadTexData(SkISize dimensions,
445 GrGLenum target,
446 SkIRect dstRect,
447 GrGLenum externalFormat,
448 GrGLenum externalType,
449 size_t bpp,
450 const GrMipLevel texels[],
451 int mipLevelCount);
452
453 // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this
454 // to populate a new texture. Returns false if we failed to create and upload the texture.
455 bool uploadCompressedTexData(SkImage::CompressionType compressionType,
456 GrGLFormat,
457 SkISize dimensions,
458 GrMipmapped,
459 GrGLenum target,
460 const void* data, size_t dataSize);
461
462 // Calls one of various versions of renderBufferStorageMultisample.
463 bool renderbufferStorageMSAA(const GrGLContext& ctx, int sampleCount, GrGLenum format,
464 int width, int height);
465
466 bool createRenderTargetObjects(const GrGLTexture::Desc&,
467 int sampleCount,
468 GrGLRenderTarget::IDs*);
469 enum TempFBOTarget {
470 kSrc_TempFBOTarget,
471 kDst_TempFBOTarget
472 };
473
474 // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
475 // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
476 // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
477 void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget,
478 TempFBOTarget tempFBOTarget);
479
480 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
481 void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget);
482
483#ifdef SK_ENABLE_DUMP_GPU
484 void onDumpJSON(SkJSONWriter*) const override;
485#endif
486
487 bool createCopyProgram(GrTexture* srcTexture);
488 bool createMipmapProgram(int progIdx);
489
490 std::unique_ptr<GrGLContext> fGLContext;
491
492 // GL program-related state
493 std::unique_ptr<ProgramCache> fProgramCache;
494
495 ///////////////////////////////////////////////////////////////////////////
496 ///@name Caching of GL State
497 ///@{
498 int fHWActiveTextureUnitIdx;
499
500 GrGLuint fHWProgramID;
501 sk_sp<GrGLProgram> fHWProgram;
502
503 enum TriState {
504 kNo_TriState,
505 kYes_TriState,
506 kUnknown_TriState
507 };
508
509 GrGLuint fTempSrcFBOID;
510 GrGLuint fTempDstFBOID;
511
512 GrGLuint fStencilClearFBOID;
513
514 // last scissor / viewport scissor state seen by the GL.
515 struct {
516 TriState fEnabled;
517 GrNativeRect fRect;
518 void invalidate() {
519 fEnabled = kUnknown_TriState;
520 fRect.invalidate();
521 }
522 } fHWScissorSettings;
523
524 class {
525 public:
526 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
527 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
528 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
529 void setDisabled() {
530 fRTOrigin = kTopLeft_GrSurfaceOrigin;
531 fWindowState.setDisabled();
532 }
533
534 void set(GrSurfaceOrigin rtOrigin, int width, int height,
535 const GrWindowRectsState& windowState) {
536 fRTOrigin = rtOrigin;
537 fWidth = width;
538 fHeight = height;
539 fWindowState = windowState;
540 }
541
542 bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height,
543 const GrWindowRectsState& windowState) const {
544 if (!this->valid()) {
545 return false;
546 }
547 if (fWindowState.numWindows() &&
548 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) {
549 return false;
550 }
551 return fWindowState == windowState;
552 }
553
554 private:
555 enum { kInvalidSurfaceOrigin = -1 };
556
557 int fRTOrigin;
558 int fWidth;
559 int fHeight;
560 GrWindowRectsState fWindowState;
561 } fHWWindowRectsState;
562
563 GrNativeRect fHWViewport;
564
565 /**
566 * Tracks vertex attrib array state.
567 */
568 class HWVertexArrayState {
569 public:
570 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
571
572 ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
573
574 void invalidate() {
575 fBoundVertexArrayIDIsValid = false;
576 fDefaultVertexArrayAttribState.invalidate();
577 if (fCoreProfileVertexArray) {
578 fCoreProfileVertexArray->invalidateCachedState();
579 }
580 }
581
582 void notifyVertexArrayDelete(GrGLuint id) {
583 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
584 // Does implicit bind to 0
585 fBoundVertexArrayID = 0;
586 }
587 }
588
589 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
590 if (!gpu->glCaps().vertexArrayObjectSupport()) {
591 SkASSERT(0 == arrayID);
592 return;
593 }
594 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
595 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
596 fBoundVertexArrayIDIsValid = true;
597 fBoundVertexArrayID = arrayID;
598 }
599 }
600
601 /**
602 * Binds the vertex array that should be used for internal draws, and returns its attrib
603 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
604 * case we use a dummy array instead.
605 *
606 * If an index buffer is provided, it will be bound to the vertex array. Otherwise the
607 * index buffer binding will be left unchanged.
608 *
609 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
610 */
611 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
612
613 private:
614 GrGLuint fBoundVertexArrayID;
615 bool fBoundVertexArrayIDIsValid;
616
617 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
618 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
619 // GrGLGpu.
620 GrGLAttribArrayState fDefaultVertexArrayAttribState;
621
622 // This is used when we're using a core profile.
623 GrGLVertexArray* fCoreProfileVertexArray;
624 } fHWVertexArrayState;
625
626 uint8_t fHWPatchVertexCount;
627
628 struct {
629 GrGLenum fGLTarget;
630 GrGpuResource::UniqueID fBoundBufferUniqueID;
631 bool fBufferZeroKnownBound;
632
633 void invalidate() {
634 fBoundBufferUniqueID.makeInvalid();
635 fBufferZeroKnownBound = false;
636 }
637 } fHWBufferState[kGrGpuBufferTypeCount];
638
639 auto* hwBufferState(GrGpuBufferType type) {
640 unsigned typeAsUInt = static_cast<unsigned>(type);
641 SkASSERT(typeAsUInt < SK_ARRAY_COUNT(fHWBufferState));
642 return &fHWBufferState[typeAsUInt];
643 }
644
645 enum class FlushType {
646 kIfRequired,
647 kForce,
648 };
649
650 // This calls glFlush if it is required for previous operations or kForce is passed.
651 void flush(FlushType flushType = FlushType::kIfRequired);
652
653 void setNeedsFlush() { fNeedsGLFlush = true; }
654
655 struct {
656 GrBlendEquation fEquation;
657 GrBlendCoeff fSrcCoeff;
658 GrBlendCoeff fDstCoeff;
659 SkPMColor4f fConstColor;
660 bool fConstColorValid;
661 TriState fEnabled;
662
663 void invalidate() {
664 fEquation = kIllegal_GrBlendEquation;
665 fSrcCoeff = kIllegal_GrBlendCoeff;
666 fDstCoeff = kIllegal_GrBlendCoeff;
667 fConstColorValid = false;
668 fEnabled = kUnknown_TriState;
669 }
670 } fHWBlendState;
671
672 TriState fMSAAEnabled;
673 TriState fHWConservativeRasterEnabled;
674
675 TriState fHWWireframeEnabled;
676
677 GrStencilSettings fHWStencilSettings;
678 GrSurfaceOrigin fHWStencilOrigin;
679 TriState fHWStencilTestEnabled;
680
681 TriState fHWWriteToColor;
682 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID;
683 TriState fHWSRGBFramebuffer;
684
685 class TextureUnitBindings {
686 public:
687 TextureUnitBindings() = default;
688 TextureUnitBindings(const TextureUnitBindings&) = delete;
689 TextureUnitBindings& operator=(const TextureUnitBindings&) = delete;
690
691 GrGpuResource::UniqueID boundID(GrGLenum target) const;
692 bool hasBeenModified(GrGLenum target) const;
693 void setBoundID(GrGLenum target, GrGpuResource::UniqueID);
694 void invalidateForScratchUse(GrGLenum target);
695 void invalidateAllTargets(bool markUnmodified);
696
697 private:
698 struct TargetBinding {
699 GrGpuResource::UniqueID fBoundResourceID;
700 bool fHasBeenModified = false;
701 };
702 TargetBinding fTargetBindings[3];
703 };
704 SkAutoTArray<TextureUnitBindings> fHWTextureUnitBindings;
705
706 GrGLfloat fHWClearColor[4];
707
708 GrGLuint fBoundDrawFramebuffer = 0;
709
710 /** IDs for copy surface program. (3 sampler types) */
711 struct {
712 GrGLuint fProgram = 0;
713 GrGLint fTextureUniform = 0;
714 GrGLint fTexCoordXformUniform = 0;
715 GrGLint fPosXformUniform = 0;
716 } fCopyPrograms[3];
717 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer;
718
719 /** IDs for texture mipmap program. (4 filter configurations) */
720 struct {
721 GrGLuint fProgram = 0;
722 GrGLint fTextureUniform = 0;
723 GrGLint fTexCoordXformUniform = 0;
724 } fMipmapPrograms[4];
725 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer;
726
727 static int TextureToCopyProgramIdx(GrTexture* texture);
728
729 static int TextureSizeToMipmapProgramIdx(int width, int height) {
730 const bool wide = (width > 1) && SkToBool(width & 0x1);
731 const bool tall = (height > 1) && SkToBool(height & 0x1);
732 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
733 }
734
735 GrPrimitiveType fLastPrimitiveType;
736
737 GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0;
738
739 class SamplerObjectCache;
740 std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
741
742 std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass;
743 GrFinishCallbacks fFinishCallbacks;
744
745 // If we've called a command that requires us to call glFlush than this will be set to true
746 // since we defer calling flush until submit time. When we call submitToGpu if this is true then
747 // we call glFlush and reset this to false.
748 bool fNeedsGLFlush = false;
749
750 SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false);
751
752 friend class GrGLPathRendering; // For accessing setTextureUnit.
753
754 typedef GrGpu INHERITED;
755};
756
757#endif
758