Line data Source code
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 "GrGLContext.h"
12 : #include "GrGLIRect.h"
13 : #include "GrGLPathRendering.h"
14 : #include "GrGLProgram.h"
15 : #include "GrGLRenderTarget.h"
16 : #include "GrGLStencilAttachment.h"
17 : #include "GrGLTexture.h"
18 : #include "GrGLVertexArray.h"
19 : #include "GrGpu.h"
20 : #include "GrTexturePriv.h"
21 : #include "GrWindowRectsState.h"
22 : #include "GrXferProcessor.h"
23 : #include "SkLRUCache.h"
24 : #include "SkTArray.h"
25 : #include "SkTypes.h"
26 :
27 : class GrGLBuffer;
28 : class GrPipeline;
29 : class GrNonInstancedMesh;
30 : class GrSwizzle;
31 :
32 : namespace gr_instanced { class GLInstancedRendering; }
33 :
34 : #ifdef SK_DEBUG
35 : #define PROGRAM_CACHE_STATS
36 : #endif
37 :
38 : class GrGLGpu final : public GrGpu {
39 : public:
40 : static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options,
41 : GrContext* context);
42 : ~GrGLGpu() override;
43 :
44 : void disconnect(DisconnectType) override;
45 :
46 0 : const GrGLContext& glContext() const { return *fGLContext; }
47 :
48 0 : const GrGLInterface* glInterface() const { return fGLContext->interface(); }
49 0 : const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
50 0 : GrGLStandard glStandard() const { return fGLContext->standard(); }
51 : GrGLVersion glVersion() const { return fGLContext->version(); }
52 : GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
53 0 : const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
54 :
55 0 : GrGLPathRendering* glPathRendering() {
56 0 : SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
57 0 : return static_cast<GrGLPathRendering*>(pathRendering());
58 : }
59 :
60 : // Used by GrGLProgram to configure OpenGL state.
61 : void bindTexture(int unitIdx, const GrSamplerParams& params, bool allowSRGBInputs,
62 : GrGLTexture* texture);
63 :
64 : void bindTexelBuffer(int unitIdx, GrPixelConfig, GrGLBuffer*);
65 :
66 : void bindImageStorage(int unitIdx, GrIOType, GrGLTexture *);
67 :
68 : void generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs, GrGLTexture* texture);
69 :
70 : bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
71 : GrPixelConfig readConfig, DrawPreference*,
72 : ReadPixelTempDrawInfo*) override;
73 :
74 : bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
75 : GrPixelConfig srcConfig, DrawPreference*,
76 : WritePixelTempDrawInfo*) override;
77 :
78 : // These functions should be used to bind GL objects. They track the GL state and skip redundant
79 : // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
80 0 : void bindVertexArray(GrGLuint id) {
81 0 : fHWVertexArrayState.setVertexArrayID(this, id);
82 0 : }
83 :
84 : // These callbacks update state tracking when GL objects are deleted. They are called from
85 : // GrGLResource onRelease functions.
86 0 : void notifyVertexArrayDelete(GrGLuint id) {
87 0 : fHWVertexArrayState.notifyVertexArrayDelete(id);
88 0 : }
89 :
90 : // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
91 : // returns the GL target the buffer was bound to.
92 : // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
93 : // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
94 : GrGLenum bindBuffer(GrBufferType type, const GrBuffer*);
95 :
96 : // Called by GrGLBuffer after its buffer object has been destroyed.
97 : void notifyBufferReleased(const GrGLBuffer*);
98 :
99 : // The GrGLGpuCommandBuffer does not buffer up draws before submitting them to the gpu.
100 : // Thus this is the implementation of the draw call for the corresponding passthrough function
101 : // on GrGLGpuCommandBuffer.
102 : void draw(const GrPipeline&,
103 : const GrPrimitiveProcessor&,
104 : const GrMesh*,
105 : int meshCount);
106 :
107 : // The GrGLGpuCommandBuffer does not buffer up draws before submitting them to the gpu.
108 : // Thus this is the implementation of the clear call for the corresponding passthrough function
109 : // on GrGLGpuCommandBuffer.
110 : void clear(const GrFixedClip&, GrColor, GrRenderTarget*);
111 :
112 : // The GrGLGpuCommandBuffer does not buffer up draws before submitting them to the gpu.
113 : // Thus this is the implementation of the clearStencil call for the corresponding passthrough
114 : // function on GrGLGpuCommandBuffer.
115 : void clearStencilClip(const GrFixedClip&, bool insideStencilMask, GrRenderTarget*);
116 :
117 0 : const GrGLContext* glContextForTesting() const override {
118 0 : return &this->glContext();
119 : }
120 :
121 : void clearStencil(GrRenderTarget*) override;
122 :
123 : GrGpuCommandBuffer* createCommandBuffer(
124 : const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
125 : const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) override;
126 :
127 0 : void invalidateBoundRenderTarget() {
128 0 : fHWBoundRenderTargetUniqueID.makeInvalid();
129 0 : }
130 :
131 : GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
132 : int width,
133 : int height) override;
134 :
135 : GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h,
136 : GrPixelConfig config,
137 : bool isRenderTarget = false) override;
138 : bool isTestingOnlyBackendTexture(GrBackendObject) const override;
139 : void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override;
140 :
141 : void resetShaderCacheForTesting() const override;
142 :
143 : void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override;
144 :
145 : GrFence SK_WARN_UNUSED_RESULT insertFence() override;
146 : bool waitFence(GrFence, uint64_t timeout) override;
147 : void deleteFence(GrFence) const override;
148 :
149 : sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore() override;
150 : void insertSemaphore(sk_sp<GrSemaphore> semaphore) override;
151 : void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
152 :
153 : void deleteSync(GrGLsync) const;
154 :
155 : void flush() override;
156 :
157 : private:
158 : GrGLGpu(GrGLContext* ctx, GrContext* context);
159 :
160 : // GrGpu overrides
161 : void onResetContext(uint32_t resetBits) override;
162 :
163 : void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
164 :
165 : GrTexture* onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
166 : const SkTArray<GrMipLevel>& texels) override;
167 : GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
168 : SkBudgeted budgeted,
169 : const SkTArray<GrMipLevel>& texels) override;
170 :
171 : GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
172 : const void* data) override;
173 : sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
174 : sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) override;
175 : sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&) override;
176 :
177 : gr_instanced::InstancedRendering* onCreateInstancedRendering() override;
178 :
179 : // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a
180 : // compatible stencil format, or negative if there is no compatible stencil format.
181 : int getCompatibleStencilIndex(GrPixelConfig config);
182 :
183 :
184 : // Returns whether the texture is successfully created. On success, the
185 : // result is stored in |info|.
186 : // The texture is populated with |texels|, if it exists.
187 : // The texture parameters are cached in |initialTexParams|.
188 : bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
189 : bool renderTarget, GrGLTexture::TexParams* initialTexParams,
190 : const SkTArray<GrMipLevel>& texels);
191 :
192 : bool onIsACopyNeededForTextureParams(GrTextureProxy*, const GrSamplerParams&,
193 : GrTextureProducer::CopyParams*,
194 : SkScalar scaleAdjust[2]) const override;
195 :
196 : // Checks whether glReadPixels can be called to get pixel values in readConfig from the
197 : // render target.
198 : bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
199 :
200 : // Checks whether glReadPixels can be called to get pixel values in readConfig from a
201 : // render target that has renderTargetConfig. This may have to create a temporary
202 : // render target and thus is less preferable than the variant that takes a render target.
203 : bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig);
204 :
205 : // Checks whether glReadPixels can be called to get pixel values in readConfig from a
206 : // render target that has the same config as surfaceForConfig. Calls one of the the two
207 : // variations above, depending on whether the surface is a render target or not.
208 : bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
209 :
210 : bool onReadPixels(GrSurface*,
211 : int left, int top,
212 : int width, int height,
213 : GrPixelConfig,
214 : void* buffer,
215 : size_t rowBytes) override;
216 :
217 : bool onWritePixels(GrSurface*,
218 : int left, int top, int width, int height,
219 : GrPixelConfig config,
220 : const SkTArray<GrMipLevel>& texels) override;
221 :
222 : bool onTransferPixels(GrSurface*,
223 : int left, int top, int width, int height,
224 : GrPixelConfig config, GrBuffer* transferBuffer,
225 : size_t offset, size_t rowBytes) override;
226 :
227 : void onResolveRenderTarget(GrRenderTarget* target) override;
228 :
229 : bool onCopySurface(GrSurface* dst,
230 : GrSurface* src,
231 : const SkIRect& srcRect,
232 : const SkIPoint& dstPoint) override;
233 :
234 : void onQueryMultisampleSpecs(GrRenderTarget*, const GrStencilSettings&,
235 : int* effectiveSampleCnt, SamplePattern*) override;
236 :
237 : // binds texture unit in GL
238 : void setTextureUnit(int unitIdx);
239 :
240 : void setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]);
241 :
242 : // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
243 : // willDrawPoints must be true if point primitives will be rendered after setting the GL state.
244 : bool flushGLState(const GrPipeline&, const GrPrimitiveProcessor&, bool willDrawPoints);
245 :
246 : // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
247 : // an into the index buffer. It does not account for vertices.startIndex() but rather the start
248 : // index is relative to the returned offset.
249 : void setupGeometry(const GrPrimitiveProcessor&,
250 : const GrNonInstancedMesh& mesh,
251 : size_t* indexOffsetInBytes);
252 :
253 : void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
254 :
255 0 : bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
256 :
257 : bool copySurfaceAsDraw(GrSurface* dst,
258 : GrSurface* src,
259 : const SkIRect& srcRect,
260 : const SkIPoint& dstPoint);
261 : void copySurfaceAsCopyTexSubImage(GrSurface* dst,
262 : GrSurface* src,
263 : const SkIRect& srcRect,
264 : const SkIPoint& dstPoint);
265 : bool copySurfaceAsBlitFramebuffer(GrSurface* dst,
266 : GrSurface* src,
267 : const SkIRect& srcRect,
268 : const SkIPoint& dstPoint);
269 : bool generateMipmap(GrGLTexture* texture, bool gammaCorrect);
270 :
271 : static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
272 :
273 : class ProgramCache : public ::SkNoncopyable {
274 : public:
275 : ProgramCache(GrGLGpu* gpu);
276 : ~ProgramCache();
277 :
278 : void abandon();
279 : GrGLProgram* refProgram(const GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&,
280 : bool hasPointSize);
281 :
282 : private:
283 : // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
284 : // shader before evicting from the cache.
285 : static const int kMaxEntries = 128;
286 :
287 : struct Entry;
288 :
289 : // binary search for entry matching desc. returns index into fEntries that matches desc or ~
290 : // of the index of where it should be inserted.
291 : int search(const GrProgramDesc& desc) const;
292 :
293 : struct DescHash {
294 0 : uint32_t operator()(const GrProgramDesc& desc) const {
295 0 : return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
296 : }
297 : };
298 :
299 : SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
300 :
301 : GrGLGpu* fGpu;
302 : #ifdef PROGRAM_CACHE_STATS
303 : int fTotalRequests;
304 : int fCacheMisses;
305 : int fHashMisses; // cache hit but hash table missed
306 : #endif
307 : };
308 :
309 : void flushColorWrite(bool writeColor);
310 : void flushDrawFace(GrDrawFace face);
311 :
312 : // flushes the scissor. see the note on flushBoundTextureAndParams about
313 : // flushing the scissor after that function is called.
314 : void flushScissor(const GrScissorState&,
315 : const GrGLIRect& rtViewport,
316 : GrSurfaceOrigin rtOrigin);
317 :
318 : // disables the scissor
319 : void disableScissor();
320 :
321 : void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*);
322 : void disableWindowRectangles();
323 :
324 : void initFSAASupport();
325 :
326 : // determines valid stencil formats
327 : void initStencilFormats();
328 :
329 : // sets a texture unit to use for texture operations other than binding a texture to a program.
330 : // ensures that such operations don't negatively interact with tracking bound textures.
331 : void setScratchTextureUnit();
332 :
333 : // bounds is region that may be modified.
334 : // nullptr means whole target. Can be an empty rect.
335 : void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds, bool disableSRGB = false);
336 :
337 : // Need not be called if flushRenderTarget is used.
338 : void flushViewport(const GrGLIRect&);
339 :
340 : void flushStencil(const GrStencilSettings&);
341 : void disableStencil();
342 :
343 : // rt is used only if useHWAA is true.
344 : void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled);
345 :
346 : void flushMinSampleShading(float minSampleShading);
347 :
348 : void flushFramebufferSRGB(bool enable);
349 :
350 : // helper for onCreateTexture and writeTexturePixels
351 : enum UploadType {
352 : kNewTexture_UploadType, // we are creating a new texture
353 : kWrite_UploadType, // we are using TexSubImage2D to copy data to an existing texture
354 : kTransfer_UploadType, // we are using a transfer buffer to copy data
355 : };
356 : bool uploadTexData(const GrSurfaceDesc& desc,
357 : GrGLenum target,
358 : UploadType uploadType,
359 : int left, int top, int width, int height,
360 : GrPixelConfig dataConfig,
361 : const SkTArray<GrMipLevel>& texels);
362 :
363 : // helper for onCreateCompressedTexture. If width and height are
364 : // set to -1, then this function will use desc.fWidth and desc.fHeight
365 : // for the size of the data. The isNewTexture flag should be set to true
366 : // whenever a new texture needs to be created. Otherwise, we assume that
367 : // the texture is already in GPU memory and that it's going to be updated
368 : // with new data.
369 : bool uploadCompressedTexData(const GrSurfaceDesc& desc,
370 : GrGLenum target,
371 : const SkTArray<GrMipLevel>& texels,
372 : UploadType uploadType = kNewTexture_UploadType,
373 : int left = 0, int top = 0,
374 : int width = -1, int height = -1);
375 :
376 : bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
377 : GrGLRenderTarget::IDDesc*);
378 :
379 : enum TempFBOTarget {
380 : kSrc_TempFBOTarget,
381 : kDst_TempFBOTarget
382 : };
383 :
384 : // Binds a surface as a FBO for copying or reading. If the surface already owns an FBO ID then
385 : // that ID is bound. If not the surface is temporarily bound to a FBO and that FBO is bound.
386 : // This must be paired with a call to unbindSurfaceFBOForPixelOps().
387 : void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
388 : TempFBOTarget tempFBOTarget);
389 :
390 : // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
391 : void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface);
392 :
393 : sk_sp<GrGLContext> fGLContext;
394 :
395 : bool createCopyProgram(GrTexture* srcTexture);
396 : bool createMipmapProgram(int progIdx);
397 : bool createWireRectProgram();
398 :
399 : // GL program-related state
400 : ProgramCache* fProgramCache;
401 :
402 : ///////////////////////////////////////////////////////////////////////////
403 : ///@name Caching of GL State
404 : ///@{
405 : int fHWActiveTextureUnitIdx;
406 : GrGLuint fHWProgramID;
407 :
408 : enum TriState {
409 : kNo_TriState,
410 : kYes_TriState,
411 : kUnknown_TriState
412 : };
413 :
414 : GrGLuint fTempSrcFBOID;
415 : GrGLuint fTempDstFBOID;
416 :
417 : GrGLuint fStencilClearFBOID;
418 :
419 : // last scissor / viewport scissor state seen by the GL.
420 : struct {
421 : TriState fEnabled;
422 : GrGLIRect fRect;
423 0 : void invalidate() {
424 0 : fEnabled = kUnknown_TriState;
425 0 : fRect.invalidate();
426 0 : }
427 : } fHWScissorSettings;
428 :
429 0 : class {
430 : public:
431 0 : bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
432 0 : void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
433 0 : bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
434 0 : void setDisabled() {
435 0 : fRTOrigin = kDefault_GrSurfaceOrigin;
436 0 : fWindowState.setDisabled();
437 0 : }
438 :
439 0 : void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
440 : const GrWindowRectsState& windowState) {
441 0 : fRTOrigin = rtOrigin;
442 0 : fViewport = viewport;
443 0 : fWindowState = windowState;
444 0 : }
445 :
446 0 : bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
447 : const GrWindowRectsState& windowState) const {
448 0 : if (!this->valid()) {
449 0 : return false;
450 : }
451 0 : if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) {
452 0 : return false;
453 : }
454 0 : return fWindowState == windowState;
455 : }
456 :
457 : private:
458 : enum { kInvalidSurfaceOrigin = -1 };
459 :
460 : int fRTOrigin;
461 : GrGLIRect fViewport;
462 : GrWindowRectsState fWindowState;
463 : } fHWWindowRectsState;
464 :
465 : GrGLIRect fHWViewport;
466 :
467 : /**
468 : * Tracks vertex attrib array state.
469 : */
470 : class HWVertexArrayState {
471 : public:
472 0 : HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
473 :
474 0 : ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
475 :
476 0 : void invalidate() {
477 0 : fBoundVertexArrayIDIsValid = false;
478 0 : fDefaultVertexArrayAttribState.invalidate();
479 0 : if (fCoreProfileVertexArray) {
480 0 : fCoreProfileVertexArray->invalidateCachedState();
481 : }
482 0 : }
483 :
484 0 : void notifyVertexArrayDelete(GrGLuint id) {
485 0 : if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
486 : // Does implicit bind to 0
487 0 : fBoundVertexArrayID = 0;
488 : }
489 0 : }
490 :
491 0 : void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
492 0 : if (!gpu->glCaps().vertexArrayObjectSupport()) {
493 0 : SkASSERT(0 == arrayID);
494 0 : return;
495 : }
496 0 : if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
497 0 : GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
498 0 : fBoundVertexArrayIDIsValid = true;
499 0 : fBoundVertexArrayID = arrayID;
500 : }
501 : }
502 :
503 : /**
504 : * Binds the vertex array that should be used for internal draws, and returns its attrib
505 : * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
506 : * case we use a dummy array instead.
507 : *
508 : * If an index buffer is privided, it will be bound to the vertex array. Otherwise the
509 : * index buffer binding will be left unchanged.
510 : *
511 : * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
512 : */
513 : GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
514 :
515 : private:
516 : GrGLuint fBoundVertexArrayID;
517 : bool fBoundVertexArrayIDIsValid;
518 :
519 : // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
520 : // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
521 : // GrGLGpu.
522 : GrGLAttribArrayState fDefaultVertexArrayAttribState;
523 :
524 : // This is used when we're using a core profile.
525 : GrGLVertexArray* fCoreProfileVertexArray;
526 : } fHWVertexArrayState;
527 :
528 0 : struct {
529 : GrGLenum fGLTarget;
530 : GrGpuResource::UniqueID fBoundBufferUniqueID;
531 : bool fBufferZeroKnownBound;
532 :
533 0 : void invalidate() {
534 0 : fBoundBufferUniqueID.makeInvalid();
535 0 : fBufferZeroKnownBound = false;
536 0 : }
537 : } fHWBufferState[kGrBufferTypeCount];
538 :
539 : struct {
540 : GrBlendEquation fEquation;
541 : GrBlendCoeff fSrcCoeff;
542 : GrBlendCoeff fDstCoeff;
543 : GrColor fConstColor;
544 : bool fConstColorValid;
545 : TriState fEnabled;
546 :
547 0 : void invalidate() {
548 0 : fEquation = static_cast<GrBlendEquation>(-1);
549 0 : fSrcCoeff = static_cast<GrBlendCoeff>(-1);
550 0 : fDstCoeff = static_cast<GrBlendCoeff>(-1);
551 0 : fConstColorValid = false;
552 0 : fEnabled = kUnknown_TriState;
553 0 : }
554 : } fHWBlendState;
555 :
556 : TriState fMSAAEnabled;
557 :
558 : GrStencilSettings fHWStencilSettings;
559 : TriState fHWStencilTestEnabled;
560 :
561 :
562 : GrDrawFace fHWDrawFace;
563 : TriState fHWWriteToColor;
564 : GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID;
565 : TriState fHWSRGBFramebuffer;
566 : SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs;
567 :
568 0 : struct Image {
569 : GrGpuResource::UniqueID fTextureUniqueID;
570 : GrIOType fIOType;
571 : };
572 : SkTArray<Image, true> fHWBoundImageStorages;
573 :
574 : struct BufferTexture {
575 0 : BufferTexture() : fTextureID(0), fKnownBound(false),
576 : fAttachedBufferUniqueID(SK_InvalidUniqueID),
577 0 : fSwizzle(GrSwizzle::RGBA()) {}
578 :
579 : GrGLuint fTextureID;
580 : bool fKnownBound;
581 : GrPixelConfig fTexelConfig;
582 : GrGpuResource::UniqueID fAttachedBufferUniqueID;
583 : GrSwizzle fSwizzle;
584 : };
585 :
586 : SkTArray<BufferTexture, true> fHWBufferTextures;
587 : int fHWMaxUsedBufferTextureUnit;
588 :
589 : // EXT_raster_multisample.
590 : TriState fHWRasterMultisampleEnabled;
591 : int fHWNumRasterSamples;
592 : ///@}
593 :
594 : /** IDs for copy surface program. (4 sampler types) */
595 : struct {
596 : GrGLuint fProgram;
597 : GrGLint fTextureUniform;
598 : GrGLint fTexCoordXformUniform;
599 : GrGLint fPosXformUniform;
600 : } fCopyPrograms[4];
601 : sk_sp<GrGLBuffer> fCopyProgramArrayBuffer;
602 :
603 : /** IDs for texture mipmap program. (4 filter configurations) */
604 : struct {
605 : GrGLuint fProgram;
606 : GrGLint fTextureUniform;
607 : GrGLint fTexCoordXformUniform;
608 : } fMipmapPrograms[4];
609 : sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer;
610 :
611 : struct {
612 : GrGLuint fProgram;
613 : GrGLint fColorUniform;
614 : GrGLint fRectUniform;
615 : } fWireRectProgram;
616 : sk_sp<GrGLBuffer> fWireRectArrayBuffer;
617 :
618 0 : static int TextureToCopyProgramIdx(GrTexture* texture) {
619 0 : switch (texture->texturePriv().samplerType()) {
620 : case kTexture2DSampler_GrSLType:
621 0 : return 0;
622 : case kITexture2DSampler_GrSLType:
623 0 : return 1;
624 : case kTexture2DRectSampler_GrSLType:
625 0 : return 2;
626 : case kTextureExternalSampler_GrSLType:
627 0 : return 3;
628 : default:
629 0 : SkFAIL("Unexpected samper type");
630 0 : return 0;
631 : }
632 : }
633 :
634 0 : static int TextureSizeToMipmapProgramIdx(int width, int height) {
635 0 : const bool wide = (width > 1) && SkToBool(width & 0x1);
636 0 : const bool tall = (height > 1) && SkToBool(height & 0x1);
637 0 : return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
638 : }
639 :
640 : float fHWMinSampleShading;
641 :
642 : typedef GrGpu INHERITED;
643 : friend class GrGLPathRendering; // For accessing setTextureUnit.
644 : friend class gr_instanced::GLInstancedRendering; // For accessing flushGLState.
645 : };
646 :
647 : #endif
|