blob: e5cd7a9a9d1de3c1edf7723de98628eaa2880fef [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00006 */
7
jvanverth39edf762014-12-22 11:44:19 -08008#ifndef GrGLGpu_DEFINED
9#define GrGLGpu_DEFINED
reed@google.comac10a2d2010-12-22 21:39:39 +000010
robertphillips@google.com6177e692013-02-28 20:16:25 +000011#include "GrGLContext.h"
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +000012#include "GrGLIRect.h"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000013#include "GrGLIndexBuffer.h"
kkinnunenccdaa042014-08-20 01:36:23 -070014#include "GrGLPathRendering.h"
bsalomon@google.com5739d2c2012-05-31 15:07:19 +000015#include "GrGLProgram.h"
bsalomon37dd3312014-11-03 08:47:23 -080016#include "GrGLRenderTarget.h"
egdaniel8dc7c3a2015-04-16 11:22:42 -070017#include "GrGLStencilAttachment.h"
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +000018#include "GrGLTexture.h"
bsalomon@google.com6918d482013-03-07 19:09:11 +000019#include "GrGLVertexArray.h"
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +000020#include "GrGLVertexBuffer.h"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000021#include "GrGpu.h"
egdaniel8dd688b2015-01-22 10:16:09 -080022#include "GrPipelineBuilder.h"
egdaniel080e6732014-12-22 07:35:52 -080023#include "GrXferProcessor.h"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000024#include "SkTypes.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000025
egdaniel8dd688b2015-01-22 10:16:09 -080026class GrPipeline;
bsalomone64eb572015-05-07 11:35:55 -070027class GrNonInstancedVertices;
egdaniel8dd688b2015-01-22 10:16:09 -080028
commit-bot@chromium.org174db772013-03-21 12:46:01 +000029#ifdef SK_DEVELOPER
jvanverth@google.com94878772013-03-12 16:00:54 +000030#define PROGRAM_CACHE_STATS
31#endif
32
bsalomon861e1032014-12-16 07:33:49 -080033class GrGLGpu : public GrGpu {
reed@google.comac10a2d2010-12-22 21:39:39 +000034public:
bsalomon682c2692015-05-22 14:01:46 -070035 static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options,
36 GrContext* context);
mtklein36352bf2015-03-25 18:17:31 -070037 ~GrGLGpu() override;
reed@google.comac10a2d2010-12-22 21:39:39 +000038
mtklein36352bf2015-03-25 18:17:31 -070039 void contextAbandoned() override;
bsalomonc8dc1f72014-08-21 13:02:13 -070040
bsalomon424cc262015-05-22 10:37:30 -070041 const GrGLContext& glContext() const { return *fGLContext; }
commit-bot@chromium.orgc9424b82013-10-30 20:03:16 +000042
bsalomon424cc262015-05-22 10:37:30 -070043 const GrGLInterface* glInterface() const { return fGLContext->interface(); }
44 const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
45 GrGLStandard glStandard() const { return fGLContext->standard(); }
46 GrGLVersion glVersion() const { return fGLContext->version(); }
47 GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
48 const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
bsalomon@google.com0b77d682011-08-19 13:28:54 +000049
kkinnunenccdaa042014-08-20 01:36:23 -070050 GrGLPathRendering* glPathRendering() {
jvanverthe9c0fc62015-04-29 11:18:05 -070051 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
kkinnunenccdaa042014-08-20 01:36:23 -070052 return static_cast<GrGLPathRendering*>(pathRendering());
cdaltonc7103a12014-08-11 14:05:05 -070053 }
54
mtklein36352bf2015-03-25 18:17:31 -070055 void discard(GrRenderTarget*) override;
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000056
kkinnunencfe62e32015-07-01 02:58:50 -070057 // Used by GrGLProgram to configure OpenGL state.
bsalomon@google.com34cccde2013-01-04 18:34:30 +000058 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
kkinnunenccdaa042014-08-20 01:36:23 -070059
bsalomon@google.com56d11e02011-11-30 19:59:08 +000060 // GrGpu overrides
bsalomond95263c2014-12-16 13:05:12 -080061 GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
mtklein36352bf2015-03-25 18:17:31 -070062 GrPixelConfig surfaceConfig) const override;
bsalomond95263c2014-12-16 13:05:12 -080063 GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
mtklein36352bf2015-03-25 18:17:31 -070064 GrPixelConfig surfaceConfig) const override;
65 bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const override;
bsalomond95263c2014-12-16 13:05:12 -080066 bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
67 int left, int top,
68 int width, int height,
69 GrPixelConfig config,
mtklein36352bf2015-03-25 18:17:31 -070070 size_t rowBytes) const override;
71 bool fullReadPixelsIsFasterThanPartial() const override;
bsalomon@google.com75f9f252012-01-31 13:35:56 +000072
mtklein36352bf2015-03-25 18:17:31 -070073 bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) override;
bsalomon@google.comeb851172013-04-15 13:51:00 +000074
bsalomon@google.com6918d482013-03-07 19:09:11 +000075 // These functions should be used to bind GL objects. They track the GL state and skip redundant
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +000076 // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
bsalomon@google.com6918d482013-03-07 19:09:11 +000077 void bindVertexArray(GrGLuint id) {
78 fHWGeometryState.setVertexArrayID(this, id);
79 }
80 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
81 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
82 }
83 void bindVertexBuffer(GrGLuint id) {
84 fHWGeometryState.setVertexBufferID(this, id);
85 }
86
87 // These callbacks update state tracking when GL objects are deleted. They are called from
88 // GrGLResource onRelease functions.
89 void notifyVertexArrayDelete(GrGLuint id) {
90 fHWGeometryState.notifyVertexArrayDelete(id);
91 }
92 void notifyVertexBufferDelete(GrGLuint id) {
93 fHWGeometryState.notifyVertexBufferDelete(id);
94 }
95 void notifyIndexBufferDelete(GrGLuint id) {
96 fHWGeometryState.notifyIndexBufferDelete(id);
97 }
bsalomon@google.com880b8fc2013-02-19 20:17:28 +000098
bsalomonf90a02b2014-11-26 12:28:00 -080099 bool copySurface(GrSurface* dst,
100 GrSurface* src,
101 const SkIRect& srcRect,
mtklein36352bf2015-03-25 18:17:31 -0700102 const SkIPoint& dstPoint) override;
joshualitta7024152014-11-03 14:16:35 -0800103
cdalton231c5fd2015-05-13 12:35:36 -0700104 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
cdalton9954bc32015-04-29 14:17:00 -0700105
joshualitt873ad0e2015-01-20 09:08:51 -0800106 void buildProgramDesc(GrProgramDesc*,
107 const GrPrimitiveProcessor&,
egdaniel8dd688b2015-01-22 10:16:09 -0800108 const GrPipeline&,
mtklein36352bf2015-03-25 18:17:31 -0700109 const GrBatchTracker&) const override;
joshualitt79f8fae2014-10-28 17:59:26 -0700110
reedf9ad5582015-06-25 21:29:25 -0700111 const GrGLContext* glContextForTesting() const override {
112 return &this->glContext();
bsalomon993a4212015-05-29 11:37:25 -0700113 }
114
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000115private:
bsalomon424cc262015-05-22 10:37:30 -0700116 GrGLGpu(GrGLContext* ctx, GrContext* context);
117
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000118 // GrGpu overrides
mtklein36352bf2015-03-25 18:17:31 -0700119 void onResetContext(uint32_t resetBits) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000120
egdanielb0e1be22015-04-22 13:27:39 -0700121 GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
122 const void* srcData, size_t rowBytes) override;
123 GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
124 GrGpuResource::LifeCycle lifeCycle,
mtklein36352bf2015-03-25 18:17:31 -0700125 const void* srcData) override;
126 GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override;
127 GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override;
bsalomon6dc6f5f2015-06-18 09:12:16 -0700128 GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
129 GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
130 GrWrapOwnership) override;
egdaniel8dc7c3a2015-04-16 11:22:42 -0700131 bool createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int width, int height) override;
132 bool attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb,
133 GrRenderTarget* rt) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000134
bsalomond95263c2014-12-16 13:05:12 -0800135 void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
mtklein36352bf2015-03-25 18:17:31 -0700136 bool canIgnoreRect) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000137
mtklein36352bf2015-03-25 18:17:31 -0700138 void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override;
joshualitt6db519c2014-10-29 08:48:18 -0700139
bsalomond95263c2014-12-16 13:05:12 -0800140 bool onReadPixels(GrRenderTarget* target,
141 int left, int top,
142 int width, int height,
143 GrPixelConfig,
144 void* buffer,
mtklein36352bf2015-03-25 18:17:31 -0700145 size_t rowBytes) override;
bsalomond95263c2014-12-16 13:05:12 -0800146
147 bool onWriteTexturePixels(GrTexture* texture,
148 int left, int top, int width, int height,
149 GrPixelConfig config, const void* buffer,
mtklein36352bf2015-03-25 18:17:31 -0700150 size_t rowBytes) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000151
mtklein36352bf2015-03-25 18:17:31 -0700152 void onResolveRenderTarget(GrRenderTarget* target) override;
bsalomon@google.com6f379512011-11-16 20:36:03 +0000153
bsalomone64eb572015-05-07 11:35:55 -0700154 void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override;
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000155
mtklein36352bf2015-03-25 18:17:31 -0700156 void clearStencil(GrRenderTarget*) override;
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000157
robertphillips754f4e92014-09-18 13:52:08 -0700158 // GrDrawTarget overrides
mtklein36352bf2015-03-25 18:17:31 -0700159 void didAddGpuTraceMarker() override;
160 void didRemoveGpuTraceMarker() override;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000161
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000162 // binds texture unit in GL
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000163 void setTextureUnit(int unitIdx);
reed@google.comac10a2d2010-12-22 21:39:39 +0000164
egdaniel8dd688b2015-01-22 10:16:09 -0800165 // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
cdaltond0a840d2015-03-16 17:19:58 -0700166 bool flushGLState(const DrawArgs&);
bsalomond95263c2014-12-16 13:05:12 -0800167
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000168 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
bsalomoncb8979d2015-05-05 09:51:38 -0700169 // an into the index buffer. It does not account for vertices.startIndex() but rather the start
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000170 // index is relative to the returned offset.
joshualitt873ad0e2015-01-20 09:08:51 -0800171 void setupGeometry(const GrPrimitiveProcessor&,
bsalomone64eb572015-05-07 11:35:55 -0700172 const GrNonInstancedVertices& vertices,
joshualittd53a8272014-11-10 16:03:14 -0800173 size_t* indexOffsetInBytes);
bsalomon@google.com7acdb8e2011-02-11 14:07:02 +0000174
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000175 // Subclasses should call this to flush the blend state.
egdaniel080e6732014-12-22 07:35:52 -0800176 void flushBlend(const GrXferProcessor::BlendInfo& blendInfo);
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000177
bsalomon424cc262015-05-22 10:37:30 -0700178 bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
bsalomon@google.com96399942012-02-13 14:39:16 +0000179
bsalomon6df86402015-06-01 10:41:49 -0700180 void copySurfaceAsDraw(GrSurface* dst,
181 GrSurface* src,
182 const SkIRect& srcRect,
183 const SkIPoint& dstPoint);
184 void copySurfaceAsCopyTexSubImage(GrSurface* dst,
185 GrSurface* src,
186 const SkIRect& srcRect,
187 const SkIPoint& dstPoint);
188 bool copySurfaceAsBlitFramebuffer(GrSurface* dst,
189 GrSurface* src,
190 const SkIRect& srcRect,
191 const SkIPoint& dstPoint);
192
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000193 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
bsalomon@google.com080773c2011-03-15 19:09:25 +0000194
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000195 class ProgramCache : public ::SkNoncopyable {
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000196 public:
bsalomon861e1032014-12-16 07:33:49 -0800197 ProgramCache(GrGLGpu* gpu);
jvanverth@google.com94878772013-03-12 16:00:54 +0000198 ~ProgramCache();
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000199
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000200 void abandon();
bsalomon6df86402015-06-01 10:41:49 -0700201 GrGLProgram* refProgram(const DrawArgs&);
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000202
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000203 private:
204 enum {
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000205 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
206 // shader before evicting from the cache.
commit-bot@chromium.orgb5564222014-03-28 15:52:18 +0000207 kMaxEntries = 128,
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000208 kHashBits = 6,
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000209 };
210
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000211 struct Entry;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000212
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000213 struct ProgDescLess;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000214
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000215 // binary search for entry matching desc. returns index into fEntries that matches desc or ~
216 // of the index of where it should be inserted.
joshualitt79f8fae2014-10-28 17:59:26 -0700217 int search(const GrProgramDesc& desc) const;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000218
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000219 // sorted array of all the entries
220 Entry* fEntries[kMaxEntries];
221 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
222 // searching fEntries.
223 Entry* fHashTable[1 << kHashBits];
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000224
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000225 int fCount;
226 unsigned int fCurrLRUStamp;
bsalomon861e1032014-12-16 07:33:49 -0800227 GrGLGpu* fGpu;
jvanverth@google.com94878772013-03-12 16:00:54 +0000228#ifdef PROGRAM_CACHE_STATS
229 int fTotalRequests;
230 int fCacheMisses;
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000231 int fHashMisses; // cache hit but hash table missed
jvanverth@google.com94878772013-03-12 16:00:54 +0000232#endif
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000233 };
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000234
bsalomon3e791242014-12-17 13:43:13 -0800235 void flushDither(bool dither);
egdaniel080e6732014-12-22 07:35:52 -0800236 void flushColorWrite(bool writeColor);
egdaniel8dd688b2015-01-22 10:16:09 -0800237 void flushDrawFace(GrPipelineBuilder::DrawFace face);
bsalomon@google.comc96cb3a2012-06-04 19:31:00 +0000238
bsalomon@google.coma3201942012-06-21 19:58:20 +0000239 // flushes the scissor. see the note on flushBoundTextureAndParams about
240 // flushing the scissor after that function is called.
bsalomon3e791242014-12-17 13:43:13 -0800241 void flushScissor(const GrScissorState&,
joshualitt77b13072014-10-27 14:51:01 -0700242 const GrGLIRect& rtViewport,
243 GrSurfaceOrigin rtOrigin);
244
245 // disables the scissor
246 void disableScissor();
bsalomon@google.coma3201942012-06-21 19:58:20 +0000247
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000248 void initFSAASupport();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000249
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000250 // determines valid stencil formats
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000251 void initStencilFormats();
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000252
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +0000253 // sets a texture unit to use for texture operations other than binding a texture to a program.
254 // ensures that such operations don't negatively interact with tracking bound textures.
255 void setScratchTextureUnit();
reed@google.comac10a2d2010-12-22 21:39:39 +0000256
egdanield803f272015-03-18 13:01:52 -0700257 // bounds is region that may be modified and therefore has to be resolved.
258 // NULL means whole target. Can be an empty rect.
259 void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
bsalomonb0bd4f62014-09-03 07:19:50 -0700260
bsalomon3e791242014-12-17 13:43:13 -0800261 void flushStencil(const GrStencilSettings&);
cdaltond0a840d2015-03-16 17:19:58 -0700262 void flushHWAAState(GrRenderTarget* rt, bool useHWAA);
bsalomon@google.com0650e812011-04-08 18:07:53 +0000263
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000264 bool configToGLFormats(GrPixelConfig config,
265 bool getSizedInternal,
266 GrGLenum* internalFormat,
267 GrGLenum* externalFormat,
268 GrGLenum* externalType);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000269 // helper for onCreateTexture and writeTexturePixels
bsalomonb15b4c12014-10-29 12:41:57 -0700270 bool uploadTexData(const GrSurfaceDesc& desc,
bsalomon@google.com1e0e6072011-11-28 18:49:37 +0000271 bool isNewTexture,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000272 int left, int top, int width, int height,
273 GrPixelConfig dataConfig,
274 const void* data,
275 size_t rowBytes);
bsalomon@google.com0650e812011-04-08 18:07:53 +0000276
krajcevski145d48c2014-06-11 16:07:50 -0700277 // helper for onCreateCompressedTexture. If width and height are
278 // set to -1, then this function will use desc.fWidth and desc.fHeight
279 // for the size of the data. The isNewTexture flag should be set to true
280 // whenever a new texture needs to be created. Otherwise, we assume that
281 // the texture is already in GPU memory and that it's going to be updated
282 // with new data.
bsalomonb15b4c12014-10-29 12:41:57 -0700283 bool uploadCompressedTexData(const GrSurfaceDesc& desc,
krajcevski145d48c2014-06-11 16:07:50 -0700284 const void* data,
285 bool isNewTexture = true,
286 int left = 0, int top = 0,
287 int width = -1, int height = -1);
krajcevski9c0e6292014-06-02 07:38:14 -0700288
egdanielb0e1be22015-04-22 13:27:39 -0700289 bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle,
290 GrGLuint texID, GrGLRenderTarget::IDDesc*);
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +0000291
egdanield803f272015-03-18 13:01:52 -0700292 enum TempFBOTarget {
293 kSrc_TempFBOTarget,
294 kDst_TempFBOTarget
295 };
egdaniel0f5f9672015-02-03 11:10:51 -0800296
egdanield803f272015-03-18 13:01:52 -0700297 GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
298 TempFBOTarget tempFBOTarget);
egdaniel0f5f9672015-02-03 11:10:51 -0800299
egdanield803f272015-03-18 13:01:52 -0700300 void unbindTextureFromFBO(GrGLenum fboTarget);
robertphillips754f4e92014-09-18 13:52:08 -0700301
reedf9ad5582015-06-25 21:29:25 -0700302 SkAutoTUnref<GrGLContext> fGLContext;
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000303
bsalomon6df86402015-06-01 10:41:49 -0700304 void createCopyProgram();
305
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000306 // GL program-related state
307 ProgramCache* fProgramCache;
bsalomon@google.com49209392012-06-05 15:13:46 +0000308
309 ///////////////////////////////////////////////////////////////////////////
310 ///@name Caching of GL State
311 ///@{
312 int fHWActiveTextureUnitIdx;
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000313 GrGLuint fHWProgramID;
bsalomon@google.com91207482013-02-12 21:45:24 +0000314
bsalomon@google.com49209392012-06-05 15:13:46 +0000315 enum TriState {
316 kNo_TriState,
317 kYes_TriState,
318 kUnknown_TriState
319 };
320
egdanield803f272015-03-18 13:01:52 -0700321 GrGLuint fTempSrcFBOID;
322 GrGLuint fTempDstFBOID;
323
324 GrGLuint fStencilClearFBOID;
bsalomondd3143b2015-02-23 09:27:45 -0800325
bsalomon@google.coma3201942012-06-21 19:58:20 +0000326 // last scissor / viewport scissor state seen by the GL.
327 struct {
328 TriState fEnabled;
329 GrGLIRect fRect;
330 void invalidate() {
331 fEnabled = kUnknown_TriState;
332 fRect.invalidate();
333 }
334 } fHWScissorSettings;
335
bsalomon424cc262015-05-22 10:37:30 -0700336 GrGLIRect fHWViewport;
bsalomon@google.coma3201942012-06-21 19:58:20 +0000337
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000338 /**
339 * Tracks bound vertex and index buffers and vertex attrib array state.
340 */
341 class HWGeometryState {
342 public:
bsalomon@google.com6918d482013-03-07 19:09:11 +0000343 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +0000344
bsalomon8780bc62015-05-13 09:56:37 -0700345 ~HWGeometryState() { SkDELETE(fVBOVertexArray); }
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000346
bsalomon@google.com6918d482013-03-07 19:09:11 +0000347 void invalidate() {
348 fBoundVertexArrayIDIsValid = false;
349 fBoundVertexBufferIDIsValid = false;
350 fDefaultVertexArrayBoundIndexBufferID = false;
351 fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
352 fDefaultVertexArrayAttribState.invalidate();
bsalomon49f085d2014-09-05 13:34:00 -0700353 if (fVBOVertexArray) {
commit-bot@chromium.orgce6da4d2013-09-09 14:55:37 +0000354 fVBOVertexArray->invalidateCachedState();
355 }
bsalomon@google.com6918d482013-03-07 19:09:11 +0000356 }
357
358 void notifyVertexArrayDelete(GrGLuint id) {
359 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
360 // Does implicit bind to 0
361 fBoundVertexArrayID = 0;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000362 }
363 }
364
bsalomon861e1032014-12-16 07:33:49 -0800365 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000366 if (!gpu->glCaps().vertexArrayObjectSupport()) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000367 SkASSERT(0 == arrayID);
bsalomon@google.com6918d482013-03-07 19:09:11 +0000368 return;
369 }
370 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
371 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
372 fBoundVertexArrayIDIsValid = true;
373 fBoundVertexArrayID = arrayID;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000374 }
375 }
376
bsalomon@google.come49ad452013-02-20 19:33:20 +0000377 void notifyVertexBufferDelete(GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000378 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
379 fBoundVertexBufferID = 0;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000380 }
bsalomon49f085d2014-09-05 13:34:00 -0700381 if (fVBOVertexArray) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000382 fVBOVertexArray->notifyVertexBufferDelete(id);
383 }
384 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000385 }
386
bsalomon@google.come49ad452013-02-20 19:33:20 +0000387 void notifyIndexBufferDelete(GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000388 if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
389 id == fDefaultVertexArrayBoundIndexBufferID) {
390 fDefaultVertexArrayBoundIndexBufferID = 0;
391 }
bsalomon49f085d2014-09-05 13:34:00 -0700392 if (fVBOVertexArray) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000393 fVBOVertexArray->notifyIndexBufferDelete(id);
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000394 }
395 }
396
bsalomon861e1032014-12-16 07:33:49 -0800397 void setVertexBufferID(GrGLGpu* gpu, GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000398 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
399 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
400 fBoundVertexBufferIDIsValid = true;
401 fBoundVertexBufferID = id;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000402 }
403 }
404
bsalomon@google.com6918d482013-03-07 19:09:11 +0000405 /**
406 * Binds the default vertex array and binds the index buffer. This is used when binding
407 * an index buffer in order to update it.
408 */
bsalomon861e1032014-12-16 07:33:49 -0800409 void setIndexBufferIDOnDefaultVertexArray(GrGLGpu* gpu, GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000410 this->setVertexArrayID(gpu, 0);
411 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
412 id != fDefaultVertexArrayBoundIndexBufferID) {
413 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
414 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
415 fDefaultVertexArrayBoundIndexBufferID = id;
416 }
417 }
418
419 /**
420 * Binds the vertex array object that should be used to render from the vertex buffer.
421 * The vertex array is bound and its attrib array state object is returned. The vertex
422 * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +0000423 * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
bsalomon@google.com6918d482013-03-07 19:09:11 +0000424 */
bsalomon861e1032014-12-16 07:33:49 -0800425 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
bsalomon@google.com6918d482013-03-07 19:09:11 +0000426 const GrGLVertexBuffer* vbuffer,
427 const GrGLIndexBuffer* ibuffer);
428
bsalomon6df86402015-06-01 10:41:49 -0700429 /** Variants of the above that takes GL buffer IDs. Note that 0 does not imply that a
430 buffer won't be bound. The "default buffer" will be bound, which is used for client-side
431 array rendering. */
432 GrGLAttribArrayState* bindArrayAndBufferToDraw(GrGLGpu* gpu, GrGLuint vbufferID);
433 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
434 GrGLuint vbufferID,
435 GrGLuint ibufferID);
436
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000437 private:
bsalomon6df86402015-06-01 10:41:49 -0700438 GrGLAttribArrayState* internalBind(GrGLGpu* gpu, GrGLuint vbufferID, GrGLuint* ibufferID);
439
bsalomon@google.com6918d482013-03-07 19:09:11 +0000440 GrGLuint fBoundVertexArrayID;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000441 GrGLuint fBoundVertexBufferID;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000442 bool fBoundVertexArrayIDIsValid;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000443 bool fBoundVertexBufferIDIsValid;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000444
bsalomon@google.com6918d482013-03-07 19:09:11 +0000445 GrGLuint fDefaultVertexArrayBoundIndexBufferID;
446 bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
447 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
jvanverth39edf762014-12-22 11:44:19 -0800448 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
449 // GrGLGpu.
bsalomon@google.com6918d482013-03-07 19:09:11 +0000450 GrGLAttribArrayState fDefaultVertexArrayAttribState;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000451
bsalomon@google.com6918d482013-03-07 19:09:11 +0000452 // This is used when we're using a core profile and the vertices are in a VBO.
453 GrGLVertexArray* fVBOVertexArray;
bsalomon@google.com49209392012-06-05 15:13:46 +0000454 } fHWGeometryState;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000455
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000456 struct {
cdalton8917d622015-05-06 13:40:21 -0700457 GrBlendEquation fEquation;
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000458 GrBlendCoeff fSrcCoeff;
459 GrBlendCoeff fDstCoeff;
460 GrColor fConstColor;
461 bool fConstColorValid;
462 TriState fEnabled;
463
464 void invalidate() {
bsalomonf7cc8772015-05-11 11:21:14 -0700465 fEquation = static_cast<GrBlendEquation>(-1);
466 fSrcCoeff = static_cast<GrBlendCoeff>(-1);
467 fDstCoeff = static_cast<GrBlendCoeff>(-1);
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000468 fConstColorValid = false;
469 fEnabled = kUnknown_TriState;
470 }
471 } fHWBlendState;
472
bsalomon6df86402015-06-01 10:41:49 -0700473 /** IDs for copy surface program. */
474 struct {
475 GrGLuint fProgram;
476 GrGLint fTextureUniform;
477 GrGLint fTexCoordXformUniform;
478 GrGLint fPosXformUniform;
479 GrGLuint fArrayBuffer;
480 } fCopyProgram;
481
egdanielb414f252014-07-29 13:15:47 -0700482 TriState fMSAAEnabled;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000483
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000484 GrStencilSettings fHWStencilSettings;
485 TriState fHWStencilTestEnabled;
kkinnunenccdaa042014-08-20 01:36:23 -0700486
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000487
egdaniel8dd688b2015-01-22 10:16:09 -0800488 GrPipelineBuilder::DrawFace fHWDrawFace;
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000489 TriState fHWWriteToColor;
490 TriState fHWDitherEnabled;
egdanield803f272015-03-18 13:01:52 -0700491 uint32_t fHWBoundRenderTargetUniqueID;
bsalomon1c63bf62014-07-22 13:09:46 -0700492 SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000493
bsalomon@google.com49209392012-06-05 15:13:46 +0000494 ///@}
bsalomon@google.com978c8c62012-05-21 14:45:49 +0000495
bsalomon@google.comfe676522011-06-17 18:12:21 +0000496 // we record what stencil format worked last time to hopefully exit early
497 // from our loop that tries stencil formats and calls check fb status.
498 int fLastSuccessfulStencilFmtIdx;
499
reed@google.comac10a2d2010-12-22 21:39:39 +0000500 typedef GrGpu INHERITED;
kkinnunenccdaa042014-08-20 01:36:23 -0700501 friend class GrGLPathRendering; // For accessing setTextureUnit.
reed@google.comac10a2d2010-12-22 21:39:39 +0000502};
503
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000504#endif