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 "GrGLIndexBuffer.h" 14 #include "GrGLPathRendering.h" 15 #include "GrGLProgram.h" 16 #include "GrGLRenderTarget.h" 17 #include "GrGLStencilAttachment.h" 18 #include "GrGLTexture.h" 19 #include "GrGLVertexArray.h" 20 #include "GrGLVertexBuffer.h" 21 #include "GrGpu.h" 22 #include "GrPipelineBuilder.h" 23 #include "GrXferProcessor.h" 24 #include "SkTypes.h" 25 26 class GrPipeline; 27 class GrNonInstancedVertices; 28 29 #ifdef SK_DEVELOPER 30 #define PROGRAM_CACHE_STATS 31 #endif 32 33 class GrGLGpu : public GrGpu { 34 public: 35 GrGLGpu(const GrGLContext& ctx, GrContext* context); 36 ~GrGLGpu() override; 37 38 void contextAbandoned() override; 39 glContext()40 const GrGLContext& glContext() const { return fGLContext; } 41 glInterface()42 const GrGLInterface* glInterface() const { return fGLContext.interface(); } ctxInfo()43 const GrGLContextInfo& ctxInfo() const { return fGLContext; } glStandard()44 GrGLStandard glStandard() const { return fGLContext.standard(); } glVersion()45 GrGLVersion glVersion() const { return fGLContext.version(); } glslGeneration()46 GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); } glCaps()47 const GrGLCaps& glCaps() const { return *fGLContext.caps(); } 48 glPathRendering()49 GrGLPathRendering* glPathRendering() { 50 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport()); 51 return static_cast<GrGLPathRendering*>(pathRendering()); 52 } 53 54 void discard(GrRenderTarget*) override; 55 56 // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL 57 // state. 58 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture); 59 60 // GrGpu overrides 61 GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig, 62 GrPixelConfig surfaceConfig) const override; 63 GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig, 64 GrPixelConfig surfaceConfig) const override; 65 bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const override; 66 bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget, 67 int left, int top, 68 int width, int height, 69 GrPixelConfig config, 70 size_t rowBytes) const override; 71 bool fullReadPixelsIsFasterThanPartial() const override; 72 73 bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) override; 74 75 // These functions should be used to bind GL objects. They track the GL state and skip redundant 76 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. bindVertexArray(GrGLuint id)77 void bindVertexArray(GrGLuint id) { 78 fHWGeometryState.setVertexArrayID(this, id); 79 } bindIndexBufferAndDefaultVertexArray(GrGLuint id)80 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) { 81 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id); 82 } bindVertexBuffer(GrGLuint id)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. notifyVertexArrayDelete(GrGLuint id)89 void notifyVertexArrayDelete(GrGLuint id) { 90 fHWGeometryState.notifyVertexArrayDelete(id); 91 } notifyVertexBufferDelete(GrGLuint id)92 void notifyVertexBufferDelete(GrGLuint id) { 93 fHWGeometryState.notifyVertexBufferDelete(id); 94 } notifyIndexBufferDelete(GrGLuint id)95 void notifyIndexBufferDelete(GrGLuint id) { 96 fHWGeometryState.notifyIndexBufferDelete(id); 97 } 98 99 bool copySurface(GrSurface* dst, 100 GrSurface* src, 101 const SkIRect& srcRect, 102 const SkIPoint& dstPoint) override; 103 104 bool canCopySurface(const GrSurface* dst, 105 const GrSurface* src, 106 const SkIRect& srcRect, 107 const SkIPoint& dstPoint) override; 108 109 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override; 110 111 void buildProgramDesc(GrProgramDesc*, 112 const GrPrimitiveProcessor&, 113 const GrPipeline&, 114 const GrBatchTracker&) const override; 115 116 private: 117 // GrGpu overrides 118 void onResetContext(uint32_t resetBits) override; 119 120 GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle, 121 const void* srcData, size_t rowBytes) override; 122 GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, 123 GrGpuResource::LifeCycle lifeCycle, 124 const void* srcData) override; 125 GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override; 126 GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override; 127 GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) override; 128 GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) override; 129 bool createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int width, int height) override; 130 bool attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb, 131 GrRenderTarget* rt) override; 132 133 void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color, 134 bool canIgnoreRect) override; 135 136 void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override; 137 138 bool onReadPixels(GrRenderTarget* target, 139 int left, int top, 140 int width, int height, 141 GrPixelConfig, 142 void* buffer, 143 size_t rowBytes) override; 144 145 bool onWriteTexturePixels(GrTexture* texture, 146 int left, int top, int width, int height, 147 GrPixelConfig config, const void* buffer, 148 size_t rowBytes) override; 149 150 void onResolveRenderTarget(GrRenderTarget* target) override; 151 152 void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override; 153 void onStencilPath(const GrPath*, const StencilPathState&) override; 154 void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override; 155 void onDrawPaths(const DrawArgs&, 156 const GrPathRange*, 157 const void* indices, 158 GrDrawTarget::PathIndexType, 159 const float transformValues[], 160 GrDrawTarget::PathTransformType, 161 int count, 162 const GrStencilSettings&) override; 163 164 void clearStencil(GrRenderTarget*) override; 165 166 // GrDrawTarget overrides 167 void didAddGpuTraceMarker() override; 168 void didRemoveGpuTraceMarker() override; 169 170 // binds texture unit in GL 171 void setTextureUnit(int unitIdx); 172 173 // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set. 174 bool flushGLState(const DrawArgs&); 175 176 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset 177 // an into the index buffer. It does not account for vertices.startIndex() but rather the start 178 // index is relative to the returned offset. 179 void setupGeometry(const GrPrimitiveProcessor&, 180 const GrNonInstancedVertices& vertices, 181 size_t* indexOffsetInBytes); 182 183 // Subclasses should call this to flush the blend state. 184 void flushBlend(const GrXferProcessor::BlendInfo& blendInfo); 185 hasExtension(const char * ext)186 bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); } 187 188 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 189 190 class ProgramCache : public ::SkNoncopyable { 191 public: 192 ProgramCache(GrGLGpu* gpu); 193 ~ProgramCache(); 194 195 void abandon(); 196 GrGLProgram* getProgram(const DrawArgs&); 197 198 private: 199 enum { 200 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new 201 // shader before evicting from the cache. 202 kMaxEntries = 128, 203 kHashBits = 6, 204 }; 205 206 struct Entry; 207 208 struct ProgDescLess; 209 210 // binary search for entry matching desc. returns index into fEntries that matches desc or ~ 211 // of the index of where it should be inserted. 212 int search(const GrProgramDesc& desc) const; 213 214 // sorted array of all the entries 215 Entry* fEntries[kMaxEntries]; 216 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary 217 // searching fEntries. 218 Entry* fHashTable[1 << kHashBits]; 219 220 int fCount; 221 unsigned int fCurrLRUStamp; 222 GrGLGpu* fGpu; 223 #ifdef PROGRAM_CACHE_STATS 224 int fTotalRequests; 225 int fCacheMisses; 226 int fHashMisses; // cache hit but hash table missed 227 #endif 228 }; 229 230 void flushDither(bool dither); 231 void flushColorWrite(bool writeColor); 232 void flushDrawFace(GrPipelineBuilder::DrawFace face); 233 234 // flushes the scissor. see the note on flushBoundTextureAndParams about 235 // flushing the scissor after that function is called. 236 void flushScissor(const GrScissorState&, 237 const GrGLIRect& rtViewport, 238 GrSurfaceOrigin rtOrigin); 239 240 // disables the scissor 241 void disableScissor(); 242 243 void initFSAASupport(); 244 245 // determines valid stencil formats 246 void initStencilFormats(); 247 248 // sets a texture unit to use for texture operations other than binding a texture to a program. 249 // ensures that such operations don't negatively interact with tracking bound textures. 250 void setScratchTextureUnit(); 251 252 // bounds is region that may be modified and therefore has to be resolved. 253 // NULL means whole target. Can be an empty rect. 254 void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds); 255 256 void flushStencil(const GrStencilSettings&); 257 void flushHWAAState(GrRenderTarget* rt, bool useHWAA); 258 259 bool configToGLFormats(GrPixelConfig config, 260 bool getSizedInternal, 261 GrGLenum* internalFormat, 262 GrGLenum* externalFormat, 263 GrGLenum* externalType); 264 // helper for onCreateTexture and writeTexturePixels 265 bool uploadTexData(const GrSurfaceDesc& desc, 266 bool isNewTexture, 267 int left, int top, int width, int height, 268 GrPixelConfig dataConfig, 269 const void* data, 270 size_t rowBytes); 271 272 // helper for onCreateCompressedTexture. If width and height are 273 // set to -1, then this function will use desc.fWidth and desc.fHeight 274 // for the size of the data. The isNewTexture flag should be set to true 275 // whenever a new texture needs to be created. Otherwise, we assume that 276 // the texture is already in GPU memory and that it's going to be updated 277 // with new data. 278 bool uploadCompressedTexData(const GrSurfaceDesc& desc, 279 const void* data, 280 bool isNewTexture = true, 281 int left = 0, int top = 0, 282 int width = -1, int height = -1); 283 284 bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle, 285 GrGLuint texID, GrGLRenderTarget::IDDesc*); 286 287 enum TempFBOTarget { 288 kSrc_TempFBOTarget, 289 kDst_TempFBOTarget 290 }; 291 292 GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport, 293 TempFBOTarget tempFBOTarget); 294 295 void unbindTextureFromFBO(GrGLenum fboTarget); 296 297 GrGLContext fGLContext; 298 299 // GL program-related state 300 ProgramCache* fProgramCache; 301 SkAutoTUnref<GrGLProgram> fCurrentProgram; 302 303 /////////////////////////////////////////////////////////////////////////// 304 ///@name Caching of GL State 305 ///@{ 306 int fHWActiveTextureUnitIdx; 307 GrGLuint fHWProgramID; 308 309 enum TriState { 310 kNo_TriState, 311 kYes_TriState, 312 kUnknown_TriState 313 }; 314 315 GrGLuint fTempSrcFBOID; 316 GrGLuint fTempDstFBOID; 317 318 GrGLuint fStencilClearFBOID; 319 320 // last scissor / viewport scissor state seen by the GL. 321 struct { 322 TriState fEnabled; 323 GrGLIRect fRect; invalidate__anon9d4ff32a0208324 void invalidate() { 325 fEnabled = kUnknown_TriState; 326 fRect.invalidate(); 327 } 328 } fHWScissorSettings; 329 330 GrGLIRect fHWViewport; 331 332 /** 333 * Tracks bound vertex and index buffers and vertex attrib array state. 334 */ 335 class HWGeometryState { 336 public: HWGeometryState()337 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); } 338 ~HWGeometryState()339 ~HWGeometryState() { SkDELETE(fVBOVertexArray); } 340 invalidate()341 void invalidate() { 342 fBoundVertexArrayIDIsValid = false; 343 fBoundVertexBufferIDIsValid = false; 344 fDefaultVertexArrayBoundIndexBufferID = false; 345 fDefaultVertexArrayBoundIndexBufferIDIsValid = false; 346 fDefaultVertexArrayAttribState.invalidate(); 347 if (fVBOVertexArray) { 348 fVBOVertexArray->invalidateCachedState(); 349 } 350 } 351 notifyVertexArrayDelete(GrGLuint id)352 void notifyVertexArrayDelete(GrGLuint id) { 353 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 354 // Does implicit bind to 0 355 fBoundVertexArrayID = 0; 356 } 357 } 358 setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)359 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 360 if (!gpu->glCaps().vertexArrayObjectSupport()) { 361 SkASSERT(0 == arrayID); 362 return; 363 } 364 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 365 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 366 fBoundVertexArrayIDIsValid = true; 367 fBoundVertexArrayID = arrayID; 368 } 369 } 370 notifyVertexBufferDelete(GrGLuint id)371 void notifyVertexBufferDelete(GrGLuint id) { 372 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) { 373 fBoundVertexBufferID = 0; 374 } 375 if (fVBOVertexArray) { 376 fVBOVertexArray->notifyVertexBufferDelete(id); 377 } 378 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id); 379 } 380 notifyIndexBufferDelete(GrGLuint id)381 void notifyIndexBufferDelete(GrGLuint id) { 382 if (fDefaultVertexArrayBoundIndexBufferIDIsValid && 383 id == fDefaultVertexArrayBoundIndexBufferID) { 384 fDefaultVertexArrayBoundIndexBufferID = 0; 385 } 386 if (fVBOVertexArray) { 387 fVBOVertexArray->notifyIndexBufferDelete(id); 388 } 389 } 390 setVertexBufferID(GrGLGpu * gpu,GrGLuint id)391 void setVertexBufferID(GrGLGpu* gpu, GrGLuint id) { 392 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) { 393 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id)); 394 fBoundVertexBufferIDIsValid = true; 395 fBoundVertexBufferID = id; 396 } 397 } 398 399 /** 400 * Binds the default vertex array and binds the index buffer. This is used when binding 401 * an index buffer in order to update it. 402 */ setIndexBufferIDOnDefaultVertexArray(GrGLGpu * gpu,GrGLuint id)403 void setIndexBufferIDOnDefaultVertexArray(GrGLGpu* gpu, GrGLuint id) { 404 this->setVertexArrayID(gpu, 0); 405 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid || 406 id != fDefaultVertexArrayBoundIndexBufferID) { 407 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id)); 408 fDefaultVertexArrayBoundIndexBufferIDIsValid = true; 409 fDefaultVertexArrayBoundIndexBufferID = id; 410 } 411 } 412 413 /** 414 * Binds the vertex array object that should be used to render from the vertex buffer. 415 * The vertex array is bound and its attrib array state object is returned. The vertex 416 * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The 417 * returned GrGLAttribArrayState should be used to set vertex attribute arrays. 418 */ 419 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu, 420 const GrGLVertexBuffer* vbuffer, 421 const GrGLIndexBuffer* ibuffer); 422 423 private: 424 GrGLuint fBoundVertexArrayID; 425 GrGLuint fBoundVertexBufferID; 426 bool fBoundVertexArrayIDIsValid; 427 bool fBoundVertexBufferIDIsValid; 428 429 GrGLuint fDefaultVertexArrayBoundIndexBufferID; 430 bool fDefaultVertexArrayBoundIndexBufferIDIsValid; 431 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 432 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 433 // GrGLGpu. 434 GrGLAttribArrayState fDefaultVertexArrayAttribState; 435 436 // This is used when we're using a core profile and the vertices are in a VBO. 437 GrGLVertexArray* fVBOVertexArray; 438 } fHWGeometryState; 439 440 struct { 441 GrBlendEquation fEquation; 442 GrBlendCoeff fSrcCoeff; 443 GrBlendCoeff fDstCoeff; 444 GrColor fConstColor; 445 bool fConstColorValid; 446 TriState fEnabled; 447 invalidate__anon9d4ff32a0308448 void invalidate() { 449 fEquation = static_cast<GrBlendEquation>(-1); 450 fSrcCoeff = static_cast<GrBlendCoeff>(-1); 451 fDstCoeff = static_cast<GrBlendCoeff>(-1); 452 fConstColorValid = false; 453 fEnabled = kUnknown_TriState; 454 } 455 } fHWBlendState; 456 457 TriState fMSAAEnabled; 458 459 GrStencilSettings fHWStencilSettings; 460 TriState fHWStencilTestEnabled; 461 462 463 GrPipelineBuilder::DrawFace fHWDrawFace; 464 TriState fHWWriteToColor; 465 TriState fHWDitherEnabled; 466 uint32_t fHWBoundRenderTargetUniqueID; 467 SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs; 468 469 ///@} 470 471 // we record what stencil format worked last time to hopefully exit early 472 // from our loop that tries stencil formats and calls check fb status. 473 int fLastSuccessfulStencilFmtIdx; 474 475 typedef GrGpu INHERITED; 476 friend class GrGLPathRendering; // For accessing setTextureUnit. 477 }; 478 479 #endif 480