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 9 10 #ifndef GrGpuGL_DEFINED 11 #define GrGpuGL_DEFINED 12 13 #include "GrBinHashKey.h" 14 #include "GrDrawState.h" 15 #include "GrGpu.h" 16 #include "GrGLContextInfo.h" 17 #include "GrGLIndexBuffer.h" 18 #include "GrGLIRect.h" 19 #include "GrGLProgram.h" 20 #include "GrGLStencilBuffer.h" 21 #include "GrGLTexture.h" 22 #include "GrGLVertexBuffer.h" 23 #include "../GrTHashCache.h" 24 25 class GrGpuGL : public GrGpu { 26 public: 27 GrGpuGL(const GrGLContextInfo& ctxInfo); 28 virtual ~GrGpuGL(); 29 30 const GrGLInterface* glInterface() const { 31 return fGLContextInfo.interface(); 32 } 33 GrGLBinding glBinding() const { return fGLContextInfo.binding(); } 34 GrGLVersion glVersion() const { return fGLContextInfo.version(); } 35 GrGLSLGeneration glslGeneration() const { 36 return fGLContextInfo.glslGeneration(); 37 } 38 39 // Used by GrGLProgram to bind necessary textures for GrGLEffects. 40 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture); 41 42 bool programUnitTest(); 43 44 // GrGpu overrides 45 virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig config) 46 const SK_OVERRIDE; 47 virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig config) 48 const SK_OVERRIDE; 49 virtual bool readPixelsWillPayForYFlip( 50 GrRenderTarget* renderTarget, 51 int left, int top, 52 int width, int height, 53 GrPixelConfig config, 54 size_t rowBytes) const SK_OVERRIDE; 55 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE; 56 57 virtual void abandonResources() SK_OVERRIDE; 58 59 private: 60 // GrGpu overrides 61 virtual void onResetContext() SK_OVERRIDE; 62 63 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, 64 const void* srcData, 65 size_t rowBytes) SK_OVERRIDE; 66 virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size, 67 bool dynamic) SK_OVERRIDE; 68 virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, 69 bool dynamic) SK_OVERRIDE; 70 virtual GrPath* onCreatePath(const SkPath&) SK_OVERRIDE; 71 virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE; 72 virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE; 73 virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt, 74 int width, 75 int height) SK_OVERRIDE; 76 virtual bool attachStencilBufferToRenderTarget( 77 GrStencilBuffer* sb, 78 GrRenderTarget* rt) SK_OVERRIDE; 79 80 virtual void onClear(const GrIRect* rect, GrColor color) SK_OVERRIDE; 81 82 virtual void onForceRenderTargetFlush() SK_OVERRIDE; 83 84 virtual bool onReadPixels(GrRenderTarget* target, 85 int left, int top, 86 int width, int height, 87 GrPixelConfig, 88 void* buffer, 89 size_t rowBytes, 90 bool invertY) SK_OVERRIDE; 91 92 virtual void onWriteTexturePixels(GrTexture* texture, 93 int left, int top, int width, int height, 94 GrPixelConfig config, const void* buffer, 95 size_t rowBytes) SK_OVERRIDE; 96 97 virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE; 98 99 virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE; 100 101 virtual void setStencilPathSettings(const GrPath&, 102 SkPath::FillType, 103 GrStencilSettings* settings) 104 SK_OVERRIDE; 105 virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; 106 107 virtual void clearStencil() SK_OVERRIDE; 108 virtual void clearStencilClip(const GrIRect& rect, 109 bool insideClip) SK_OVERRIDE; 110 virtual bool flushGraphicsState(DrawType) SK_OVERRIDE; 111 112 const GrGLCaps& glCaps() const { return fGLContextInfo.caps(); } 113 114 // binds texture unit in GL 115 void setTextureUnit(int unitIdx); 116 117 // Sets up vertex attribute pointers and strides. On return startIndexOffset specifies an 118 // offset into the index buffer to the first index to be read (in addition to 119 // info.startIndex()). It accounts for the fact that index buffer pool may have provided space 120 // in the middle of a larger index buffer. 121 void setupGeometry(const DrawInfo& info, int* startIndexOffset); 122 // binds appropriate vertex and index buffers, also returns any extra verts or indices to 123 // offset by based on how space was allocated in pool VB/IBs. 124 void setBuffers(bool indexed, int* extraVertexOffset, int* extraIndexOffset); 125 126 // Subclasses should call this to flush the blend state. 127 // The params should be the final coefficients to apply 128 // (after any blending optimizations or dual source blending considerations 129 // have been accounted for). 130 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); 131 132 bool hasExtension(const char* ext) const { 133 return fGLContextInfo.hasExtension(ext); 134 } 135 136 const GrGLContextInfo& glContextInfo() const { return fGLContextInfo; } 137 138 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 139 140 // for readability of function impls 141 typedef GrGLProgram::Desc ProgramDesc; 142 143 class ProgramCache : public ::GrNoncopyable { 144 public: 145 ProgramCache(const GrGLContextInfo& gl); 146 147 void abandon(); 148 GrGLProgram* getProgram(const GrGLProgram::Desc& desc, const GrEffectStage* stages[]); 149 private: 150 enum { 151 kKeySize = sizeof(ProgramDesc), 152 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new 153 // shader before evicting from the cache. 154 kMaxEntries = 32 155 }; 156 157 class Entry; 158 // The value of the hash key is based on the ProgramDesc. 159 typedef GrTBinHashKey<Entry, kKeySize> ProgramHashKey; 160 161 class Entry : public ::GrNoncopyable { 162 public: 163 Entry() : fProgram(NULL), fLRUStamp(0) {} 164 Entry& operator = (const Entry& entry) { 165 GrSafeRef(entry.fProgram.get()); 166 fProgram.reset(entry.fProgram.get()); 167 fKey = entry.fKey; 168 fLRUStamp = entry.fLRUStamp; 169 return *this; 170 } 171 int compare(const ProgramHashKey& key) const { 172 return fKey.compare(key); 173 } 174 175 public: 176 SkAutoTUnref<GrGLProgram> fProgram; 177 ProgramHashKey fKey; 178 unsigned int fLRUStamp; // Move outside entry? 179 }; 180 181 GrTHashTable<Entry, ProgramHashKey, 8> fHashCache; 182 183 Entry fEntries[kMaxEntries]; 184 int fCount; 185 unsigned int fCurrLRUStamp; 186 const GrGLContextInfo& fGL; 187 }; 188 189 // sets the color specified by GrDrawState::setColor() 190 void flushColor(GrColor color); 191 192 // sets the color specified by GrDrawState::setCoverage() 193 void flushCoverage(GrColor color); 194 195 // sets the MVP matrix uniform for currently bound program 196 void flushViewMatrix(DrawType type); 197 198 199 // flushes dithering, color-mask, and face culling stat 200 void flushMiscFixedFunctionState(); 201 202 // flushes the scissor. see the note on flushBoundTextureAndParams about 203 // flushing the scissor after that function is called. 204 void flushScissor(); 205 206 void buildProgram(bool isPoints, 207 BlendOptFlags blendOpts, 208 GrBlendCoeff dstCoeff, 209 ProgramDesc* desc); 210 211 // Inits GrDrawTarget::Caps, subclass may enable additional caps. 212 void initCaps(); 213 214 void initFSAASupport(); 215 216 // determines valid stencil formats 217 void initStencilFormats(); 218 219 // notify callbacks to update state tracking when related 220 // objects are bound to GL or deleted outside of the class 221 void notifyVertexBufferBind(const GrGLVertexBuffer* buffer); 222 void notifyVertexBufferDelete(const GrGLVertexBuffer* buffer); 223 void notifyIndexBufferBind(const GrGLIndexBuffer* buffer); 224 void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer); 225 void notifyTextureDelete(GrGLTexture* texture); 226 void notifyRenderTargetDelete(GrRenderTarget* renderTarget); 227 228 void setSpareTextureUnit(); 229 230 // bound is region that may be modified and therefore has to be resolved. 231 // NULL means whole target. Can be an empty rect. 232 void flushRenderTarget(const GrIRect* bound); 233 void flushStencil(DrawType); 234 void flushAAState(DrawType); 235 236 bool configToGLFormats(GrPixelConfig config, 237 bool getSizedInternal, 238 GrGLenum* internalFormat, 239 GrGLenum* externalFormat, 240 GrGLenum* externalType); 241 // helper for onCreateTexture and writeTexturePixels 242 bool uploadTexData(const GrGLTexture::Desc& desc, 243 bool isNewTexture, 244 int left, int top, int width, int height, 245 GrPixelConfig dataConfig, 246 const void* data, 247 size_t rowBytes); 248 249 bool createRenderTargetObjects(int width, int height, 250 GrGLuint texID, 251 GrGLRenderTarget::Desc* desc); 252 253 void fillInConfigRenderableTable(); 254 255 friend class GrGLVertexBuffer; 256 friend class GrGLIndexBuffer; 257 friend class GrGLTexture; 258 friend class GrGLRenderTarget; 259 260 GrGLContextInfo fGLContextInfo; 261 262 // GL program-related state 263 ProgramCache* fProgramCache; 264 SkAutoTUnref<GrGLProgram> fCurrentProgram; 265 266 /////////////////////////////////////////////////////////////////////////// 267 ///@name Caching of GL State 268 ///@{ 269 int fHWActiveTextureUnitIdx; 270 GrGLuint fHWProgramID; 271 GrColor fHWConstAttribColor; 272 GrColor fHWConstAttribCoverage; 273 274 enum TriState { 275 kNo_TriState, 276 kYes_TriState, 277 kUnknown_TriState 278 }; 279 280 // last scissor / viewport scissor state seen by the GL. 281 struct { 282 TriState fEnabled; 283 GrGLIRect fRect; 284 void invalidate() { 285 fEnabled = kUnknown_TriState; 286 fRect.invalidate(); 287 } 288 } fHWScissorSettings; 289 290 GrGLIRect fHWViewport; 291 292 struct { 293 size_t fVertexOffset; 294 GrVertexLayout fVertexLayout; 295 const GrVertexBuffer* fVertexBuffer; 296 const GrIndexBuffer* fIndexBuffer; 297 bool fArrayPtrsDirty; 298 } fHWGeometryState; 299 300 struct { 301 GrBlendCoeff fSrcCoeff; 302 GrBlendCoeff fDstCoeff; 303 GrColor fConstColor; 304 bool fConstColorValid; 305 TriState fEnabled; 306 307 void invalidate() { 308 fSrcCoeff = kInvalid_GrBlendCoeff; 309 fDstCoeff = kInvalid_GrBlendCoeff; 310 fConstColorValid = false; 311 fEnabled = kUnknown_TriState; 312 } 313 } fHWBlendState; 314 315 struct { 316 TriState fMSAAEnabled; 317 TriState fSmoothLineEnabled; 318 void invalidate() { 319 fMSAAEnabled = kUnknown_TriState; 320 fSmoothLineEnabled = kUnknown_TriState; 321 } 322 } fHWAAState; 323 324 struct { 325 SkMatrix fViewMatrix; 326 SkISize fRTSize; 327 void invalidate() { 328 fViewMatrix = SkMatrix::InvalidMatrix(); 329 fRTSize.fWidth = -1; // just make the first value compared illegal. 330 } 331 } fHWPathMatrixState; 332 333 GrStencilSettings fHWStencilSettings; 334 TriState fHWStencilTestEnabled; 335 336 GrDrawState::DrawFace fHWDrawFace; 337 TriState fHWWriteToColor; 338 TriState fHWDitherEnabled; 339 GrRenderTarget* fHWBoundRenderTarget; 340 GrTexture* fHWBoundTextures[GrDrawState::kNumStages]; 341 ///@} 342 343 // we record what stencil format worked last time to hopefully exit early 344 // from our loop that tries stencil formats and calls check fb status. 345 int fLastSuccessfulStencilFmtIdx; 346 347 bool fPrintedCaps; 348 349 typedef GrGpu INHERITED; 350 }; 351 352 #endif 353