blob: baafea3f1ee97e00ef29ca263741b850c9d890e7 [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
joshualitt1c735482015-07-13 08:08:25 -070073 bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const 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
jvanverth672bb7f2015-07-13 07:19:57 -0700115 GrBackendObject createBackendTexture(void* pixels, int w, int h,
116 GrPixelConfig config) const override;
117 bool isBackendTexture(GrBackendObject id) const override;
118 void deleteBackendTexture(GrBackendObject id) const override;
119
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000120private:
bsalomon424cc262015-05-22 10:37:30 -0700121 GrGLGpu(GrGLContext* ctx, GrContext* context);
122
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000123 // GrGpu overrides
mtklein36352bf2015-03-25 18:17:31 -0700124 void onResetContext(uint32_t resetBits) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000125
egdanielb0e1be22015-04-22 13:27:39 -0700126 GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
127 const void* srcData, size_t rowBytes) override;
128 GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
129 GrGpuResource::LifeCycle lifeCycle,
mtklein36352bf2015-03-25 18:17:31 -0700130 const void* srcData) override;
131 GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override;
132 GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override;
bsalomon6dc6f5f2015-06-18 09:12:16 -0700133 GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
134 GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
135 GrWrapOwnership) override;
egdaniel8dc7c3a2015-04-16 11:22:42 -0700136 bool createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int width, int height) override;
137 bool attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb,
138 GrRenderTarget* rt) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000139
bsalomond95263c2014-12-16 13:05:12 -0800140 void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
mtklein36352bf2015-03-25 18:17:31 -0700141 bool canIgnoreRect) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000142
mtklein36352bf2015-03-25 18:17:31 -0700143 void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override;
joshualitt6db519c2014-10-29 08:48:18 -0700144
bsalomond95263c2014-12-16 13:05:12 -0800145 bool onReadPixels(GrRenderTarget* target,
146 int left, int top,
147 int width, int height,
148 GrPixelConfig,
149 void* buffer,
mtklein36352bf2015-03-25 18:17:31 -0700150 size_t rowBytes) override;
bsalomond95263c2014-12-16 13:05:12 -0800151
152 bool onWriteTexturePixels(GrTexture* texture,
153 int left, int top, int width, int height,
154 GrPixelConfig config, const void* buffer,
mtklein36352bf2015-03-25 18:17:31 -0700155 size_t rowBytes) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000156
mtklein36352bf2015-03-25 18:17:31 -0700157 void onResolveRenderTarget(GrRenderTarget* target) override;
bsalomon@google.com6f379512011-11-16 20:36:03 +0000158
bsalomone64eb572015-05-07 11:35:55 -0700159 void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override;
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000160
mtklein36352bf2015-03-25 18:17:31 -0700161 void clearStencil(GrRenderTarget*) override;
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000162
robertphillips754f4e92014-09-18 13:52:08 -0700163 // GrDrawTarget overrides
mtklein36352bf2015-03-25 18:17:31 -0700164 void didAddGpuTraceMarker() override;
165 void didRemoveGpuTraceMarker() override;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000166
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000167 // binds texture unit in GL
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000168 void setTextureUnit(int unitIdx);
reed@google.comac10a2d2010-12-22 21:39:39 +0000169
egdaniel8dd688b2015-01-22 10:16:09 -0800170 // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
cdaltond0a840d2015-03-16 17:19:58 -0700171 bool flushGLState(const DrawArgs&);
bsalomond95263c2014-12-16 13:05:12 -0800172
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000173 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
bsalomoncb8979d2015-05-05 09:51:38 -0700174 // an into the index buffer. It does not account for vertices.startIndex() but rather the start
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000175 // index is relative to the returned offset.
joshualitt873ad0e2015-01-20 09:08:51 -0800176 void setupGeometry(const GrPrimitiveProcessor&,
bsalomone64eb572015-05-07 11:35:55 -0700177 const GrNonInstancedVertices& vertices,
joshualittd53a8272014-11-10 16:03:14 -0800178 size_t* indexOffsetInBytes);
bsalomon@google.com7acdb8e2011-02-11 14:07:02 +0000179
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000180 // Subclasses should call this to flush the blend state.
egdaniel080e6732014-12-22 07:35:52 -0800181 void flushBlend(const GrXferProcessor::BlendInfo& blendInfo);
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000182
bsalomon424cc262015-05-22 10:37:30 -0700183 bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
bsalomon@google.com96399942012-02-13 14:39:16 +0000184
bsalomon6df86402015-06-01 10:41:49 -0700185 void copySurfaceAsDraw(GrSurface* dst,
186 GrSurface* src,
187 const SkIRect& srcRect,
188 const SkIPoint& dstPoint);
189 void copySurfaceAsCopyTexSubImage(GrSurface* dst,
190 GrSurface* src,
191 const SkIRect& srcRect,
192 const SkIPoint& dstPoint);
193 bool copySurfaceAsBlitFramebuffer(GrSurface* dst,
194 GrSurface* src,
195 const SkIRect& srcRect,
196 const SkIPoint& dstPoint);
197
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000198 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
bsalomon@google.com080773c2011-03-15 19:09:25 +0000199
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000200 class ProgramCache : public ::SkNoncopyable {
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000201 public:
bsalomon861e1032014-12-16 07:33:49 -0800202 ProgramCache(GrGLGpu* gpu);
jvanverth@google.com94878772013-03-12 16:00:54 +0000203 ~ProgramCache();
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000204
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000205 void abandon();
bsalomon6df86402015-06-01 10:41:49 -0700206 GrGLProgram* refProgram(const DrawArgs&);
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000207
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000208 private:
209 enum {
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000210 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
211 // shader before evicting from the cache.
commit-bot@chromium.orgb5564222014-03-28 15:52:18 +0000212 kMaxEntries = 128,
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000213 kHashBits = 6,
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000214 };
215
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000216 struct Entry;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000217
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000218 struct ProgDescLess;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000219
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000220 // binary search for entry matching desc. returns index into fEntries that matches desc or ~
221 // of the index of where it should be inserted.
joshualitt79f8fae2014-10-28 17:59:26 -0700222 int search(const GrProgramDesc& desc) const;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000223
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000224 // sorted array of all the entries
225 Entry* fEntries[kMaxEntries];
226 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
227 // searching fEntries.
228 Entry* fHashTable[1 << kHashBits];
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000229
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000230 int fCount;
231 unsigned int fCurrLRUStamp;
bsalomon861e1032014-12-16 07:33:49 -0800232 GrGLGpu* fGpu;
jvanverth@google.com94878772013-03-12 16:00:54 +0000233#ifdef PROGRAM_CACHE_STATS
234 int fTotalRequests;
235 int fCacheMisses;
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000236 int fHashMisses; // cache hit but hash table missed
jvanverth@google.com94878772013-03-12 16:00:54 +0000237#endif
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000238 };
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000239
bsalomon3e791242014-12-17 13:43:13 -0800240 void flushDither(bool dither);
egdaniel080e6732014-12-22 07:35:52 -0800241 void flushColorWrite(bool writeColor);
egdaniel8dd688b2015-01-22 10:16:09 -0800242 void flushDrawFace(GrPipelineBuilder::DrawFace face);
bsalomon@google.comc96cb3a2012-06-04 19:31:00 +0000243
bsalomon@google.coma3201942012-06-21 19:58:20 +0000244 // flushes the scissor. see the note on flushBoundTextureAndParams about
245 // flushing the scissor after that function is called.
bsalomon3e791242014-12-17 13:43:13 -0800246 void flushScissor(const GrScissorState&,
joshualitt77b13072014-10-27 14:51:01 -0700247 const GrGLIRect& rtViewport,
248 GrSurfaceOrigin rtOrigin);
249
250 // disables the scissor
251 void disableScissor();
bsalomon@google.coma3201942012-06-21 19:58:20 +0000252
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000253 void initFSAASupport();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000254
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000255 // determines valid stencil formats
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000256 void initStencilFormats();
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000257
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +0000258 // sets a texture unit to use for texture operations other than binding a texture to a program.
259 // ensures that such operations don't negatively interact with tracking bound textures.
260 void setScratchTextureUnit();
reed@google.comac10a2d2010-12-22 21:39:39 +0000261
egdanield803f272015-03-18 13:01:52 -0700262 // bounds is region that may be modified and therefore has to be resolved.
263 // NULL means whole target. Can be an empty rect.
264 void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
bsalomonb0bd4f62014-09-03 07:19:50 -0700265
bsalomon3e791242014-12-17 13:43:13 -0800266 void flushStencil(const GrStencilSettings&);
cdaltond0a840d2015-03-16 17:19:58 -0700267 void flushHWAAState(GrRenderTarget* rt, bool useHWAA);
bsalomon@google.com0650e812011-04-08 18:07:53 +0000268
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000269 bool configToGLFormats(GrPixelConfig config,
270 bool getSizedInternal,
271 GrGLenum* internalFormat,
272 GrGLenum* externalFormat,
jvanverth672bb7f2015-07-13 07:19:57 -0700273 GrGLenum* externalType) const;
bsalomon@google.com6f379512011-11-16 20:36:03 +0000274 // helper for onCreateTexture and writeTexturePixels
bsalomonb15b4c12014-10-29 12:41:57 -0700275 bool uploadTexData(const GrSurfaceDesc& desc,
bsalomon@google.com1e0e6072011-11-28 18:49:37 +0000276 bool isNewTexture,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000277 int left, int top, int width, int height,
278 GrPixelConfig dataConfig,
279 const void* data,
280 size_t rowBytes);
bsalomon@google.com0650e812011-04-08 18:07:53 +0000281
krajcevski145d48c2014-06-11 16:07:50 -0700282 // helper for onCreateCompressedTexture. If width and height are
283 // set to -1, then this function will use desc.fWidth and desc.fHeight
284 // for the size of the data. The isNewTexture flag should be set to true
285 // whenever a new texture needs to be created. Otherwise, we assume that
286 // the texture is already in GPU memory and that it's going to be updated
287 // with new data.
bsalomonb15b4c12014-10-29 12:41:57 -0700288 bool uploadCompressedTexData(const GrSurfaceDesc& desc,
krajcevski145d48c2014-06-11 16:07:50 -0700289 const void* data,
290 bool isNewTexture = true,
291 int left = 0, int top = 0,
292 int width = -1, int height = -1);
krajcevski9c0e6292014-06-02 07:38:14 -0700293
egdanielb0e1be22015-04-22 13:27:39 -0700294 bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle,
295 GrGLuint texID, GrGLRenderTarget::IDDesc*);
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +0000296
egdanield803f272015-03-18 13:01:52 -0700297 enum TempFBOTarget {
298 kSrc_TempFBOTarget,
299 kDst_TempFBOTarget
300 };
egdaniel0f5f9672015-02-03 11:10:51 -0800301
egdanield803f272015-03-18 13:01:52 -0700302 GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
303 TempFBOTarget tempFBOTarget);
egdaniel0f5f9672015-02-03 11:10:51 -0800304
egdanield803f272015-03-18 13:01:52 -0700305 void unbindTextureFromFBO(GrGLenum fboTarget);
robertphillips754f4e92014-09-18 13:52:08 -0700306
reedf9ad5582015-06-25 21:29:25 -0700307 SkAutoTUnref<GrGLContext> fGLContext;
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000308
bsalomon6df86402015-06-01 10:41:49 -0700309 void createCopyProgram();
310
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000311 // GL program-related state
312 ProgramCache* fProgramCache;
bsalomon@google.com49209392012-06-05 15:13:46 +0000313
314 ///////////////////////////////////////////////////////////////////////////
315 ///@name Caching of GL State
316 ///@{
317 int fHWActiveTextureUnitIdx;
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000318 GrGLuint fHWProgramID;
bsalomon@google.com91207482013-02-12 21:45:24 +0000319
bsalomon@google.com49209392012-06-05 15:13:46 +0000320 enum TriState {
321 kNo_TriState,
322 kYes_TriState,
323 kUnknown_TriState
324 };
325
egdanield803f272015-03-18 13:01:52 -0700326 GrGLuint fTempSrcFBOID;
327 GrGLuint fTempDstFBOID;
328
329 GrGLuint fStencilClearFBOID;
bsalomondd3143b2015-02-23 09:27:45 -0800330
bsalomon@google.coma3201942012-06-21 19:58:20 +0000331 // last scissor / viewport scissor state seen by the GL.
332 struct {
333 TriState fEnabled;
334 GrGLIRect fRect;
335 void invalidate() {
336 fEnabled = kUnknown_TriState;
337 fRect.invalidate();
338 }
339 } fHWScissorSettings;
340
bsalomon424cc262015-05-22 10:37:30 -0700341 GrGLIRect fHWViewport;
bsalomon@google.coma3201942012-06-21 19:58:20 +0000342
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000343 /**
344 * Tracks bound vertex and index buffers and vertex attrib array state.
345 */
346 class HWGeometryState {
347 public:
bsalomon@google.com6918d482013-03-07 19:09:11 +0000348 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +0000349
bsalomon8780bc62015-05-13 09:56:37 -0700350 ~HWGeometryState() { SkDELETE(fVBOVertexArray); }
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000351
bsalomon@google.com6918d482013-03-07 19:09:11 +0000352 void invalidate() {
353 fBoundVertexArrayIDIsValid = false;
354 fBoundVertexBufferIDIsValid = false;
355 fDefaultVertexArrayBoundIndexBufferID = false;
356 fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
357 fDefaultVertexArrayAttribState.invalidate();
bsalomon49f085d2014-09-05 13:34:00 -0700358 if (fVBOVertexArray) {
commit-bot@chromium.orgce6da4d2013-09-09 14:55:37 +0000359 fVBOVertexArray->invalidateCachedState();
360 }
bsalomon@google.com6918d482013-03-07 19:09:11 +0000361 }
362
363 void notifyVertexArrayDelete(GrGLuint id) {
364 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
365 // Does implicit bind to 0
366 fBoundVertexArrayID = 0;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000367 }
368 }
369
bsalomon861e1032014-12-16 07:33:49 -0800370 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000371 if (!gpu->glCaps().vertexArrayObjectSupport()) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000372 SkASSERT(0 == arrayID);
bsalomon@google.com6918d482013-03-07 19:09:11 +0000373 return;
374 }
375 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
376 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
377 fBoundVertexArrayIDIsValid = true;
378 fBoundVertexArrayID = arrayID;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000379 }
380 }
381
bsalomon@google.come49ad452013-02-20 19:33:20 +0000382 void notifyVertexBufferDelete(GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000383 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
384 fBoundVertexBufferID = 0;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000385 }
bsalomon49f085d2014-09-05 13:34:00 -0700386 if (fVBOVertexArray) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000387 fVBOVertexArray->notifyVertexBufferDelete(id);
388 }
389 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000390 }
391
bsalomon@google.come49ad452013-02-20 19:33:20 +0000392 void notifyIndexBufferDelete(GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000393 if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
394 id == fDefaultVertexArrayBoundIndexBufferID) {
395 fDefaultVertexArrayBoundIndexBufferID = 0;
396 }
bsalomon49f085d2014-09-05 13:34:00 -0700397 if (fVBOVertexArray) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000398 fVBOVertexArray->notifyIndexBufferDelete(id);
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000399 }
400 }
401
bsalomon861e1032014-12-16 07:33:49 -0800402 void setVertexBufferID(GrGLGpu* gpu, GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000403 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
404 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
405 fBoundVertexBufferIDIsValid = true;
406 fBoundVertexBufferID = id;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000407 }
408 }
409
bsalomon@google.com6918d482013-03-07 19:09:11 +0000410 /**
411 * Binds the default vertex array and binds the index buffer. This is used when binding
412 * an index buffer in order to update it.
413 */
bsalomon861e1032014-12-16 07:33:49 -0800414 void setIndexBufferIDOnDefaultVertexArray(GrGLGpu* gpu, GrGLuint id) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000415 this->setVertexArrayID(gpu, 0);
416 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
417 id != fDefaultVertexArrayBoundIndexBufferID) {
418 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
419 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
420 fDefaultVertexArrayBoundIndexBufferID = id;
421 }
422 }
423
424 /**
425 * Binds the vertex array object that should be used to render from the vertex buffer.
426 * The vertex array is bound and its attrib array state object is returned. The vertex
427 * 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 +0000428 * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
bsalomon@google.com6918d482013-03-07 19:09:11 +0000429 */
bsalomon861e1032014-12-16 07:33:49 -0800430 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
bsalomon@google.com6918d482013-03-07 19:09:11 +0000431 const GrGLVertexBuffer* vbuffer,
432 const GrGLIndexBuffer* ibuffer);
433
bsalomon6df86402015-06-01 10:41:49 -0700434 /** Variants of the above that takes GL buffer IDs. Note that 0 does not imply that a
435 buffer won't be bound. The "default buffer" will be bound, which is used for client-side
436 array rendering. */
437 GrGLAttribArrayState* bindArrayAndBufferToDraw(GrGLGpu* gpu, GrGLuint vbufferID);
438 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
439 GrGLuint vbufferID,
440 GrGLuint ibufferID);
441
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000442 private:
bsalomon6df86402015-06-01 10:41:49 -0700443 GrGLAttribArrayState* internalBind(GrGLGpu* gpu, GrGLuint vbufferID, GrGLuint* ibufferID);
444
bsalomon@google.com6918d482013-03-07 19:09:11 +0000445 GrGLuint fBoundVertexArrayID;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000446 GrGLuint fBoundVertexBufferID;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000447 bool fBoundVertexArrayIDIsValid;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000448 bool fBoundVertexBufferIDIsValid;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000449
bsalomon@google.com6918d482013-03-07 19:09:11 +0000450 GrGLuint fDefaultVertexArrayBoundIndexBufferID;
451 bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
452 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
jvanverth39edf762014-12-22 11:44:19 -0800453 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
454 // GrGLGpu.
bsalomon@google.com6918d482013-03-07 19:09:11 +0000455 GrGLAttribArrayState fDefaultVertexArrayAttribState;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000456
bsalomon@google.com6918d482013-03-07 19:09:11 +0000457 // This is used when we're using a core profile and the vertices are in a VBO.
458 GrGLVertexArray* fVBOVertexArray;
bsalomon@google.com49209392012-06-05 15:13:46 +0000459 } fHWGeometryState;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000460
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000461 struct {
cdalton8917d622015-05-06 13:40:21 -0700462 GrBlendEquation fEquation;
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000463 GrBlendCoeff fSrcCoeff;
464 GrBlendCoeff fDstCoeff;
465 GrColor fConstColor;
466 bool fConstColorValid;
467 TriState fEnabled;
468
469 void invalidate() {
bsalomonf7cc8772015-05-11 11:21:14 -0700470 fEquation = static_cast<GrBlendEquation>(-1);
471 fSrcCoeff = static_cast<GrBlendCoeff>(-1);
472 fDstCoeff = static_cast<GrBlendCoeff>(-1);
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000473 fConstColorValid = false;
474 fEnabled = kUnknown_TriState;
475 }
476 } fHWBlendState;
477
bsalomon6df86402015-06-01 10:41:49 -0700478 /** IDs for copy surface program. */
479 struct {
480 GrGLuint fProgram;
481 GrGLint fTextureUniform;
482 GrGLint fTexCoordXformUniform;
483 GrGLint fPosXformUniform;
484 GrGLuint fArrayBuffer;
485 } fCopyProgram;
486
egdanielb414f252014-07-29 13:15:47 -0700487 TriState fMSAAEnabled;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000488
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000489 GrStencilSettings fHWStencilSettings;
490 TriState fHWStencilTestEnabled;
kkinnunenccdaa042014-08-20 01:36:23 -0700491
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000492
egdaniel8dd688b2015-01-22 10:16:09 -0800493 GrPipelineBuilder::DrawFace fHWDrawFace;
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000494 TriState fHWWriteToColor;
495 TriState fHWDitherEnabled;
egdanield803f272015-03-18 13:01:52 -0700496 uint32_t fHWBoundRenderTargetUniqueID;
bsalomon1c63bf62014-07-22 13:09:46 -0700497 SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000498
bsalomon@google.com49209392012-06-05 15:13:46 +0000499 ///@}
bsalomon@google.com978c8c62012-05-21 14:45:49 +0000500
bsalomon@google.comfe676522011-06-17 18:12:21 +0000501 // we record what stencil format worked last time to hopefully exit early
502 // from our loop that tries stencil formats and calls check fb status.
503 int fLastSuccessfulStencilFmtIdx;
504
reed@google.comac10a2d2010-12-22 21:39:39 +0000505 typedef GrGpu INHERITED;
kkinnunenccdaa042014-08-20 01:36:23 -0700506 friend class GrGLPathRendering; // For accessing setTextureUnit.
reed@google.comac10a2d2010-12-22 21:39:39 +0000507};
508
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000509#endif