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 #include "GrGpuGL.h" 10 #include "GrGLStencilBuffer.h" 11 #include "GrGLPath.h" 12 #include "GrGLShaderBuilder.h" 13 #include "GrTemplates.h" 14 #include "GrTypes.h" 15 #include "SkTemplates.h" 16 17 static const GrGLuint GR_MAX_GLUINT = ~0U; 18 static const GrGLint GR_INVAL_GLINT = ~0; 19 20 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) 21 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) 22 23 // we use a spare texture unit to avoid 24 // mucking with the state of any of the stages. 25 static const int SPARE_TEX_UNIT = GrDrawState::kNumStages; 26 27 #define SKIP_CACHE_CHECK true 28 29 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR 30 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) 31 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) 32 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) 33 #else 34 #define CLEAR_ERROR_BEFORE_ALLOC(iface) 35 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call) 36 #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR 37 #endif 38 39 40 /////////////////////////////////////////////////////////////////////////////// 41 42 static const GrGLenum gXfermodeCoeff2Blend[] = { 43 GR_GL_ZERO, 44 GR_GL_ONE, 45 GR_GL_SRC_COLOR, 46 GR_GL_ONE_MINUS_SRC_COLOR, 47 GR_GL_DST_COLOR, 48 GR_GL_ONE_MINUS_DST_COLOR, 49 GR_GL_SRC_ALPHA, 50 GR_GL_ONE_MINUS_SRC_ALPHA, 51 GR_GL_DST_ALPHA, 52 GR_GL_ONE_MINUS_DST_ALPHA, 53 GR_GL_CONSTANT_COLOR, 54 GR_GL_ONE_MINUS_CONSTANT_COLOR, 55 GR_GL_CONSTANT_ALPHA, 56 GR_GL_ONE_MINUS_CONSTANT_ALPHA, 57 58 // extended blend coeffs 59 GR_GL_SRC1_COLOR, 60 GR_GL_ONE_MINUS_SRC1_COLOR, 61 GR_GL_SRC1_ALPHA, 62 GR_GL_ONE_MINUS_SRC1_ALPHA, 63 }; 64 65 bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { 66 static const bool gCoeffReferencesBlendConst[] = { 67 false, 68 false, 69 false, 70 false, 71 false, 72 false, 73 false, 74 false, 75 false, 76 false, 77 true, 78 true, 79 true, 80 true, 81 82 // extended blend coeffs 83 false, 84 false, 85 false, 86 false, 87 }; 88 return gCoeffReferencesBlendConst[coeff]; 89 GR_STATIC_ASSERT(kTotalGrBlendCoeffCount == 90 GR_ARRAY_COUNT(gCoeffReferencesBlendConst)); 91 92 GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff); 93 GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff); 94 GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff); 95 GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff); 96 GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff); 97 GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff); 98 GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff); 99 GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff); 100 GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff); 101 GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff); 102 GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff); 103 GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff); 104 GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff); 105 GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff); 106 107 GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff); 108 GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff); 109 GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff); 110 GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff); 111 112 // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope 113 GR_STATIC_ASSERT(kTotalGrBlendCoeffCount == 114 GR_ARRAY_COUNT(gXfermodeCoeff2Blend)); 115 } 116 117 /////////////////////////////////////////////////////////////////////////////// 118 119 static bool gPrintStartupSpew; 120 121 static bool fbo_test(const GrGLInterface* gl, int w, int h) { 122 123 GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); 124 125 GrGLuint testFBO; 126 GR_GL_CALL(gl, GenFramebuffers(1, &testFBO)); 127 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, testFBO)); 128 GrGLuint testRTTex; 129 GR_GL_CALL(gl, GenTextures(1, &testRTTex)); 130 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, testRTTex)); 131 // some implementations require texture to be mip-map complete before 132 // FBO with level 0 bound as color attachment will be framebuffer complete. 133 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, 134 GR_GL_TEXTURE_MIN_FILTER, 135 GR_GL_NEAREST)); 136 GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D, 0, GR_GL_RGBA, w, h, 137 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, NULL)); 138 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0)); 139 GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER, 140 GR_GL_COLOR_ATTACHMENT0, 141 GR_GL_TEXTURE_2D, testRTTex, 0)); 142 GrGLenum status; 143 GR_GL_CALL_RET(gl, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 144 GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO)); 145 GR_GL_CALL(gl, DeleteTextures(1, &testRTTex)); 146 147 return status == GR_GL_FRAMEBUFFER_COMPLETE; 148 } 149 150 GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo) : fGLContextInfo(ctxInfo) { 151 152 GrAssert(ctxInfo.isInitialized()); 153 154 fillInConfigRenderableTable(); 155 156 fPrintedCaps = false; 157 158 GrGLClearErr(fGLContextInfo.interface()); 159 160 if (gPrintStartupSpew) { 161 const GrGLubyte* ext; 162 GL_CALL_RET(ext, GetString(GR_GL_EXTENSIONS)); 163 const GrGLubyte* vendor; 164 const GrGLubyte* renderer; 165 const GrGLubyte* version; 166 GL_CALL_RET(vendor, GetString(GR_GL_VENDOR)); 167 GL_CALL_RET(renderer, GetString(GR_GL_RENDERER)); 168 GL_CALL_RET(version, GetString(GR_GL_VERSION)); 169 GrPrintf("------------------------- create GrGpuGL %p --------------\n", 170 this); 171 GrPrintf("------ VENDOR %s\n", vendor); 172 GrPrintf("------ RENDERER %s\n", renderer); 173 GrPrintf("------ VERSION %s\n", version); 174 GrPrintf("------ EXTENSIONS\n %s \n", ext); 175 } 176 177 this->initCaps(); 178 179 fProgramCache = SkNEW_ARGS(ProgramCache, (this->glContextInfo())); 180 181 fLastSuccessfulStencilFmtIdx = 0; 182 if (false) { // avoid bit rot, suppress warning 183 fbo_test(this->glInterface(), 0, 0); 184 } 185 } 186 187 GrGpuGL::~GrGpuGL() { 188 if (0 != fHWProgramID) { 189 // detach the current program so there is no confusion on OpenGL's part 190 // that we want it to be deleted 191 GrAssert(fHWProgramID == fCurrentProgram->fProgramID); 192 GL_CALL(UseProgram(0)); 193 } 194 195 delete fProgramCache; 196 197 // This must be called by before the GrDrawTarget destructor 198 this->releaseGeometry(); 199 // This subclass must do this before the base class destructor runs 200 // since we will unref the GrGLInterface. 201 this->releaseResources(); 202 } 203 204 /////////////////////////////////////////////////////////////////////////////// 205 206 void GrGpuGL::initCaps() { 207 GrGLint maxTextureUnits; 208 // check FS and fixed-function texture unit limits 209 // we only use textures in the fragment stage currently. 210 // checks are > to make sure we have a spare unit. 211 const GrGLInterface* gl = this->glInterface(); 212 GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); 213 GrAssert(maxTextureUnits > GrDrawState::kNumStages); 214 215 CapsInternals* caps = this->capsInternals(); 216 217 GrGLint numFormats; 218 GR_GL_GetIntegerv(gl, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats); 219 SkAutoSTMalloc<10, GrGLint> formats(numFormats); 220 GR_GL_GetIntegerv(gl, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats); 221 for (int i = 0; i < numFormats; ++i) { 222 if (formats[i] == GR_GL_PALETTE8_RGBA8) { 223 caps->f8BitPaletteSupport = true; 224 break; 225 } 226 } 227 228 if (kDesktop_GrGLBinding == this->glBinding()) { 229 // we could also look for GL_ATI_separate_stencil extension or 230 // GL_EXT_stencil_two_side but they use different function signatures 231 // than GL2.0+ (and than each other). 232 caps->fTwoSidedStencilSupport = (this->glVersion() >= GR_GL_VER(2,0)); 233 // supported on GL 1.4 and higher or by extension 234 caps->fStencilWrapOpsSupport = (this->glVersion() >= GR_GL_VER(1,4)) || 235 this->hasExtension("GL_EXT_stencil_wrap"); 236 } else { 237 // ES 2 has two sided stencil and stencil wrap 238 caps->fTwoSidedStencilSupport = true; 239 caps->fStencilWrapOpsSupport = true; 240 } 241 242 if (kDesktop_GrGLBinding == this->glBinding()) { 243 caps->fBufferLockSupport = true; // we require VBO support and the desktop VBO 244 // extension includes glMapBuffer. 245 } else { 246 caps->fBufferLockSupport = this->hasExtension("GL_OES_mapbuffer"); 247 } 248 249 if (kDesktop_GrGLBinding == this->glBinding()) { 250 if (this->glVersion() >= GR_GL_VER(2,0) || 251 this->hasExtension("GL_ARB_texture_non_power_of_two")) { 252 caps->fNPOTTextureTileSupport = true; 253 } else { 254 caps->fNPOTTextureTileSupport = false; 255 } 256 } else { 257 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only 258 caps->fNPOTTextureTileSupport = this->hasExtension("GL_OES_texture_npot"); 259 } 260 261 caps->fHWAALineSupport = (kDesktop_GrGLBinding == this->glBinding()); 262 263 GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_SIZE, &caps->fMaxTextureSize); 264 GR_GL_GetIntegerv(gl, GR_GL_MAX_RENDERBUFFER_SIZE, &caps->fMaxRenderTargetSize); 265 // Our render targets are always created with textures as the color 266 // attachment, hence this min: 267 caps->fMaxRenderTargetSize = GrMin(caps->fMaxTextureSize, caps->fMaxRenderTargetSize); 268 269 caps->fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType(); 270 caps->fPathStencilingSupport = GR_GL_USE_NV_PATH_RENDERING && 271 this->hasExtension("GL_NV_path_rendering"); 272 273 // Enable supported shader-related caps 274 if (kDesktop_GrGLBinding == this->glBinding()) { 275 caps->fDualSourceBlendingSupport = 276 this->glVersion() >= GR_GL_VER(3,3) || 277 this->hasExtension("GL_ARB_blend_func_extended"); 278 caps->fShaderDerivativeSupport = true; 279 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS 280 caps->fGeometryShaderSupport = 281 this->glVersion() >= GR_GL_VER(3,2) && 282 this->glslGeneration() >= k150_GrGLSLGeneration; 283 } else { 284 caps->fShaderDerivativeSupport = 285 this->hasExtension("GL_OES_standard_derivatives"); 286 } 287 } 288 289 void GrGpuGL::fillInConfigRenderableTable() { 290 291 // OpenGL < 3.0 292 // no support for render targets unless the GL_ARB_framebuffer_object 293 // extension is supported (in which case we get ALPHA, RED, RG, RGB, 294 // RGBA (ALPHA8, RGBA4, RGBA8) for OpenGL > 1.1). Note that we 295 // probably don't get R8 in this case. 296 297 // OpenGL 3.0 298 // base color renderable: ALPHA, RED, RG, RGB, and RGBA 299 // sized derivatives: ALPHA8, R8, RGBA4, RGBA8 300 301 // >= OpenGL 3.1 302 // base color renderable: RED, RG, RGB, and RGBA 303 // sized derivatives: R8, RGBA4, RGBA8 304 // if the GL_ARB_compatibility extension is supported then we get back 305 // support for GL_ALPHA and ALPHA8 306 307 // GL_EXT_bgra adds BGRA render targets to any version 308 309 // ES 2.0 310 // color renderable: RGBA4, RGB5_A1, RGB565 311 // GL_EXT_texture_rg adds support for R8 as a color render target 312 // GL_OES_rgb8_rgba8 and/or GL_ARM_rgba8 adds support for RGBA8 313 // GL_EXT_texture_format_BGRA8888 and/or GL_APPLE_texture_format_BGRA8888 314 // added BGRA support 315 316 if (kDesktop_GrGLBinding == this->glBinding()) { 317 // Post 3.0 we will get R8 318 // Prior to 3.0 we will get ALPHA8 (with GL_ARB_framebuffer_object) 319 if (this->glVersion() >= GR_GL_VER(3,0) || 320 this->hasExtension("GL_ARB_framebuffer_object")) { 321 fConfigRenderSupport[kAlpha_8_GrPixelConfig] = true; 322 } 323 } else { 324 // On ES we can only hope for R8 325 fConfigRenderSupport[kAlpha_8_GrPixelConfig] = 326 this->glCaps().textureRedSupport(); 327 } 328 329 if (kDesktop_GrGLBinding != this->glBinding()) { 330 // only available in ES 331 fConfigRenderSupport[kRGB_565_GrPixelConfig] = true; 332 } 333 334 // Pre 3.0, Ganesh relies on either GL_ARB_framebuffer_object or 335 // GL_EXT_framebuffer_object for FBO support. Both of these 336 // allow RGBA4 render targets so this is always supported. 337 fConfigRenderSupport[kRGBA_4444_GrPixelConfig] = true; 338 339 if (this->glCaps().rgba8RenderbufferSupport()) { 340 fConfigRenderSupport[kRGBA_8888_GrPixelConfig] = true; 341 } 342 343 if (this->glCaps().bgraFormatSupport()) { 344 fConfigRenderSupport[kBGRA_8888_GrPixelConfig] = true; 345 } 346 } 347 348 GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig config) const { 349 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) { 350 return GrPixelConfigSwapRAndB(config); 351 } else { 352 return config; 353 } 354 } 355 356 GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig config) const { 357 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) { 358 return GrPixelConfigSwapRAndB(config); 359 } else { 360 return config; 361 } 362 } 363 364 bool GrGpuGL::fullReadPixelsIsFasterThanPartial() const { 365 return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL); 366 } 367 368 void GrGpuGL::onResetContext() { 369 if (gPrintStartupSpew && !fPrintedCaps) { 370 fPrintedCaps = true; 371 this->getCaps().print(); 372 this->glCaps().print(); 373 } 374 375 // we don't use the zb at all 376 GL_CALL(Disable(GR_GL_DEPTH_TEST)); 377 GL_CALL(DepthMask(GR_GL_FALSE)); 378 379 fHWDrawFace = GrDrawState::kInvalid_DrawFace; 380 fHWDitherEnabled = kUnknown_TriState; 381 382 if (kDesktop_GrGLBinding == this->glBinding()) { 383 // Desktop-only state that we never change 384 GL_CALL(Disable(GR_GL_POINT_SMOOTH)); 385 GL_CALL(Disable(GR_GL_LINE_SMOOTH)); 386 GL_CALL(Disable(GR_GL_POLYGON_SMOOTH)); 387 GL_CALL(Disable(GR_GL_POLYGON_STIPPLE)); 388 GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP)); 389 if (this->glCaps().imagingSupport()) { 390 GL_CALL(Disable(GR_GL_COLOR_TABLE)); 391 } 392 GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP)); 393 GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL)); 394 // Since ES doesn't support glPointSize at all we always use the VS to 395 // set the point size 396 GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE)); 397 398 // We should set glPolygonMode(FRONT_AND_BACK,FILL) here, too. It isn't 399 // currently part of our gl interface. There are probably others as 400 // well. 401 } 402 fHWAAState.invalidate(); 403 fHWWriteToColor = kUnknown_TriState; 404 405 // we only ever use lines in hairline mode 406 GL_CALL(LineWidth(1)); 407 408 // invalid 409 fHWActiveTextureUnitIdx = -1; 410 411 fHWBlendState.invalidate(); 412 413 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 414 fHWBoundTextures[s] = NULL; 415 } 416 417 fHWScissorSettings.invalidate(); 418 419 fHWViewport.invalidate(); 420 421 fHWStencilSettings.invalidate(); 422 fHWStencilTestEnabled = kUnknown_TriState; 423 424 fHWGeometryState.fIndexBuffer = NULL; 425 fHWGeometryState.fVertexBuffer = NULL; 426 427 fHWGeometryState.fArrayPtrsDirty = true; 428 429 fHWBoundRenderTarget = NULL; 430 431 fHWPathMatrixState.invalidate(); 432 if (fCaps.pathStencilingSupport()) { 433 // we don't use the model view matrix. 434 GL_CALL(MatrixMode(GR_GL_MODELVIEW)); 435 GL_CALL(LoadIdentity()); 436 } 437 438 // we assume these values 439 if (this->glCaps().unpackRowLengthSupport()) { 440 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 441 } 442 if (this->glCaps().packRowLengthSupport()) { 443 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 444 } 445 if (this->glCaps().unpackFlipYSupport()) { 446 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 447 } 448 if (this->glCaps().packFlipYSupport()) { 449 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE)); 450 } 451 452 fHWGeometryState.fVertexOffset = ~0U; 453 454 // Third party GL code may have left vertex attributes enabled. Some GL 455 // implementations (osmesa) may read vetex attributes that are not required 456 // by the current shader. Therefore, we have to ensure that only the 457 // attributes we require for the current draw are enabled or we may cause an 458 // invalid read. 459 460 // Disable all vertex layout bits so that next flush will assume all 461 // optional vertex attributes are disabled. 462 fHWGeometryState.fVertexLayout = 0; 463 464 // We always use the this attribute and assume it is always enabled. 465 int posAttrIdx = GrGLProgram::PositionAttributeIdx(); 466 GL_CALL(EnableVertexAttribArray(posAttrIdx)); 467 // Disable all other vertex attributes. 468 for (int va = 0; va < this->glCaps().maxVertexAttributes(); ++va) { 469 if (va != posAttrIdx) { 470 GL_CALL(DisableVertexAttribArray(va)); 471 } 472 } 473 474 fHWProgramID = 0; 475 fHWConstAttribColor = GrColor_ILLEGAL; 476 fHWConstAttribCoverage = GrColor_ILLEGAL; 477 } 478 479 GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) { 480 if (!this->configToGLFormats(desc.fConfig, false, NULL, NULL, NULL)) { 481 return NULL; 482 } 483 484 if (0 == desc.fTextureHandle) { 485 return NULL; 486 } 487 488 // FIXME: add support for TopLeft RT's by flipping all draws. 489 if (desc.fFlags & kRenderTarget_GrBackendTextureFlag && 490 kBottomLeft_GrSurfaceOrigin != desc.fOrigin) { 491 return NULL; 492 } 493 494 int maxSize = this->getCaps().maxTextureSize(); 495 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 496 return NULL; 497 } 498 499 GrGLTexture::Desc glTexDesc; 500 // next line relies on GrBackendTextureDesc's flags matching GrTexture's 501 glTexDesc.fFlags = (GrTextureFlags) desc.fFlags; 502 glTexDesc.fWidth = desc.fWidth; 503 glTexDesc.fHeight = desc.fHeight; 504 glTexDesc.fConfig = desc.fConfig; 505 glTexDesc.fSampleCnt = desc.fSampleCnt; 506 glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle); 507 glTexDesc.fIsWrapped = true; 508 glTexDesc.fOrigin = desc.fOrigin; 509 510 GrGLTexture* texture = NULL; 511 if (desc.fFlags & kRenderTarget_GrBackendTextureFlag) { 512 GrGLRenderTarget::Desc glRTDesc; 513 glRTDesc.fRTFBOID = 0; 514 glRTDesc.fTexFBOID = 0; 515 glRTDesc.fMSColorRenderbufferID = 0; 516 glRTDesc.fConfig = desc.fConfig; 517 glRTDesc.fSampleCnt = desc.fSampleCnt; 518 if (!this->createRenderTargetObjects(glTexDesc.fWidth, 519 glTexDesc.fHeight, 520 glTexDesc.fTextureID, 521 &glRTDesc)) { 522 return NULL; 523 } 524 texture = SkNEW_ARGS(GrGLTexture, (this, glTexDesc, glRTDesc)); 525 } else { 526 texture = SkNEW_ARGS(GrGLTexture, (this, glTexDesc)); 527 } 528 if (NULL == texture) { 529 return NULL; 530 } 531 532 this->setSpareTextureUnit(); 533 return texture; 534 } 535 536 GrRenderTarget* GrGpuGL::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 537 GrGLRenderTarget::Desc glDesc; 538 glDesc.fConfig = desc.fConfig; 539 glDesc.fRTFBOID = static_cast<GrGLuint>(desc.fRenderTargetHandle); 540 glDesc.fMSColorRenderbufferID = 0; 541 glDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 542 glDesc.fSampleCnt = desc.fSampleCnt; 543 glDesc.fIsWrapped = true; 544 GrGLIRect viewport; 545 viewport.fLeft = 0; 546 viewport.fBottom = 0; 547 viewport.fWidth = desc.fWidth; 548 viewport.fHeight = desc.fHeight; 549 550 GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget, 551 (this, glDesc, viewport)); 552 if (desc.fStencilBits) { 553 GrGLStencilBuffer::Format format; 554 format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat; 555 format.fPacked = false; 556 format.fStencilBits = desc.fStencilBits; 557 format.fTotalBits = desc.fStencilBits; 558 static const bool kIsSBWrapped = false; 559 GrGLStencilBuffer* sb = SkNEW_ARGS(GrGLStencilBuffer, 560 (this, 561 kIsSBWrapped, 562 0, 563 desc.fWidth, 564 desc.fHeight, 565 desc.fSampleCnt, 566 format)); 567 tgt->setStencilBuffer(sb); 568 sb->unref(); 569 } 570 return tgt; 571 } 572 573 //////////////////////////////////////////////////////////////////////////////// 574 575 void GrGpuGL::onWriteTexturePixels(GrTexture* texture, 576 int left, int top, int width, int height, 577 GrPixelConfig config, const void* buffer, 578 size_t rowBytes) { 579 if (NULL == buffer) { 580 return; 581 } 582 GrGLTexture* glTex = static_cast<GrGLTexture*>(texture); 583 584 this->setSpareTextureUnit(); 585 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); 586 GrGLTexture::Desc desc; 587 desc.fFlags = glTex->desc().fFlags; 588 desc.fWidth = glTex->width(); 589 desc.fHeight = glTex->height(); 590 desc.fConfig = glTex->config(); 591 desc.fSampleCnt = glTex->desc().fSampleCnt; 592 desc.fTextureID = glTex->textureID(); 593 desc.fOrigin = glTex->origin(); 594 595 this->uploadTexData(desc, false, 596 left, top, width, height, 597 config, buffer, rowBytes); 598 } 599 600 namespace { 601 bool adjust_pixel_ops_params(int surfaceWidth, 602 int surfaceHeight, 603 size_t bpp, 604 int* left, int* top, int* width, int* height, 605 const void** data, 606 size_t* rowBytes) { 607 if (!*rowBytes) { 608 *rowBytes = *width * bpp; 609 } 610 611 GrIRect subRect = GrIRect::MakeXYWH(*left, *top, *width, *height); 612 GrIRect bounds = GrIRect::MakeWH(surfaceWidth, surfaceHeight); 613 614 if (!subRect.intersect(bounds)) { 615 return false; 616 } 617 *data = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>(*data) + 618 (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp); 619 620 *left = subRect.fLeft; 621 *top = subRect.fTop; 622 *width = subRect.width(); 623 *height = subRect.height(); 624 return true; 625 } 626 } 627 628 bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc, 629 bool isNewTexture, 630 int left, int top, int width, int height, 631 GrPixelConfig dataConfig, 632 const void* data, 633 size_t rowBytes) { 634 GrAssert(NULL != data || isNewTexture); 635 636 size_t bpp = GrBytesPerPixel(dataConfig); 637 if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top, 638 &width, &height, &data, &rowBytes)) { 639 return false; 640 } 641 size_t trimRowBytes = width * bpp; 642 643 // in case we need a temporary, trimmed copy of the src pixels 644 SkAutoSMalloc<128 * 128> tempStorage; 645 646 // paletted textures cannot be partially updated 647 bool useTexStorage = isNewTexture && 648 desc.fConfig != kIndex_8_GrPixelConfig && 649 this->glCaps().texStorageSupport(); 650 651 if (useTexStorage && kDesktop_GrGLBinding == this->glBinding()) { 652 // 565 is not a sized internal format on desktop GL. So on desktop with 653 // 565 we always use an unsized internal format to let the system pick 654 // the best sized format to convert the 565 data to. Since TexStorage 655 // only allows sized internal formats we will instead use TexImage2D. 656 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; 657 } 658 659 GrGLenum internalFormat; 660 GrGLenum externalFormat; 661 GrGLenum externalType; 662 // glTexStorage requires sized internal formats on both desktop and ES. ES 663 // glTexImage requires an unsized format. 664 if (!this->configToGLFormats(dataConfig, useTexStorage, &internalFormat, 665 &externalFormat, &externalType)) { 666 return false; 667 } 668 669 if (!isNewTexture && GR_GL_PALETTE8_RGBA8 == internalFormat) { 670 // paletted textures cannot be updated 671 return false; 672 } 673 674 /* 675 * check whether to allocate a temporary buffer for flipping y or 676 * because our srcData has extra bytes past each row. If so, we need 677 * to trim those off here, since GL ES may not let us specify 678 * GL_UNPACK_ROW_LENGTH. 679 */ 680 bool restoreGLRowLength = false; 681 bool swFlipY = false; 682 bool glFlipY = false; 683 if (NULL != data) { 684 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 685 if (this->glCaps().unpackFlipYSupport()) { 686 glFlipY = true; 687 } else { 688 swFlipY = true; 689 } 690 } 691 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { 692 // can't use this for flipping, only non-neg values allowed. :( 693 if (rowBytes != trimRowBytes) { 694 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); 695 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); 696 restoreGLRowLength = true; 697 } 698 } else { 699 if (trimRowBytes != rowBytes || swFlipY) { 700 // copy data into our new storage, skipping the trailing bytes 701 size_t trimSize = height * trimRowBytes; 702 const char* src = (const char*)data; 703 if (swFlipY) { 704 src += (height - 1) * rowBytes; 705 } 706 char* dst = (char*)tempStorage.reset(trimSize); 707 for (int y = 0; y < height; y++) { 708 memcpy(dst, src, trimRowBytes); 709 if (swFlipY) { 710 src -= rowBytes; 711 } else { 712 src += rowBytes; 713 } 714 dst += trimRowBytes; 715 } 716 // now point data to our copied version 717 data = tempStorage.get(); 718 } 719 } 720 if (glFlipY) { 721 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); 722 } 723 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, static_cast<GrGLint>(bpp))); 724 } 725 bool succeeded = true; 726 if (isNewTexture && 727 0 == left && 0 == top && 728 desc.fWidth == width && desc.fHeight == height) { 729 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 730 if (useTexStorage) { 731 // We never resize or change formats of textures. We don't use 732 // mipmaps currently. 733 GL_ALLOC_CALL(this->glInterface(), 734 TexStorage2D(GR_GL_TEXTURE_2D, 735 1, // levels 736 internalFormat, 737 desc.fWidth, desc.fHeight)); 738 } else { 739 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { 740 GrGLsizei imageSize = desc.fWidth * desc.fHeight + 741 kGrColorTableSize; 742 GL_ALLOC_CALL(this->glInterface(), 743 CompressedTexImage2D(GR_GL_TEXTURE_2D, 744 0, // level 745 internalFormat, 746 desc.fWidth, desc.fHeight, 747 0, // border 748 imageSize, 749 data)); 750 } else { 751 GL_ALLOC_CALL(this->glInterface(), 752 TexImage2D(GR_GL_TEXTURE_2D, 753 0, // level 754 internalFormat, 755 desc.fWidth, desc.fHeight, 756 0, // border 757 externalFormat, externalType, 758 data)); 759 } 760 } 761 GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface()); 762 if (error != GR_GL_NO_ERROR) { 763 succeeded = false; 764 } else { 765 // if we have data and we used TexStorage to create the texture, we 766 // now upload with TexSubImage. 767 if (NULL != data && useTexStorage) { 768 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, 769 0, // level 770 left, top, 771 width, height, 772 externalFormat, externalType, 773 data)); 774 } 775 } 776 } else { 777 if (swFlipY || glFlipY) { 778 top = desc.fHeight - (top + height); 779 } 780 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, 781 0, // level 782 left, top, 783 width, height, 784 externalFormat, externalType, data)); 785 } 786 787 if (restoreGLRowLength) { 788 GrAssert(this->glCaps().unpackRowLengthSupport()); 789 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 790 } 791 if (glFlipY) { 792 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 793 } 794 return succeeded; 795 } 796 797 namespace { 798 bool renderbuffer_storage_msaa(GrGLContextInfo& ctxInfo, 799 int sampleCount, 800 GrGLenum format, 801 int width, int height) { 802 CLEAR_ERROR_BEFORE_ALLOC(ctxInfo.interface()); 803 GrAssert(GrGLCaps::kNone_MSFBOType != ctxInfo.caps().msFBOType()); 804 bool created = false; 805 if (GrGLCaps::kNVDesktop_CoverageAAType == 806 ctxInfo.caps().coverageAAType()) { 807 const GrGLCaps::MSAACoverageMode& mode = 808 ctxInfo.caps().getMSAACoverageMode(sampleCount); 809 GL_ALLOC_CALL(ctxInfo.interface(), 810 RenderbufferStorageMultisampleCoverage(GR_GL_RENDERBUFFER, 811 mode.fCoverageSampleCnt, 812 mode.fColorSampleCnt, 813 format, 814 width, height)); 815 created = (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctxInfo.interface())); 816 } 817 if (!created) { 818 // glRBMS will fail if requested samples is > max samples. 819 sampleCount = GrMin(sampleCount, ctxInfo.caps().maxSampleCount()); 820 GL_ALLOC_CALL(ctxInfo.interface(), 821 RenderbufferStorageMultisample(GR_GL_RENDERBUFFER, 822 sampleCount, 823 format, 824 width, height)); 825 created = (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctxInfo.interface())); 826 } 827 return created; 828 } 829 } 830 831 bool GrGpuGL::createRenderTargetObjects(int width, int height, 832 GrGLuint texID, 833 GrGLRenderTarget::Desc* desc) { 834 desc->fMSColorRenderbufferID = 0; 835 desc->fRTFBOID = 0; 836 desc->fTexFBOID = 0; 837 desc->fIsWrapped = false; 838 839 GrGLenum status; 840 841 GrGLenum msColorFormat = 0; // suppress warning 842 843 GL_CALL(GenFramebuffers(1, &desc->fTexFBOID)); 844 if (!desc->fTexFBOID) { 845 goto FAILED; 846 } 847 848 849 // If we are using multisampling we will create two FBOS. We render 850 // to one and then resolve to the texture bound to the other. 851 if (desc->fSampleCnt > 0) { 852 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) { 853 goto FAILED; 854 } 855 GL_CALL(GenFramebuffers(1, &desc->fRTFBOID)); 856 GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID)); 857 if (!desc->fRTFBOID || 858 !desc->fMSColorRenderbufferID || 859 !this->configToGLFormats(desc->fConfig, 860 // GLES requires sized internal formats 861 kES2_GrGLBinding == this->glBinding(), 862 &msColorFormat, NULL, NULL)) { 863 goto FAILED; 864 } 865 } else { 866 desc->fRTFBOID = desc->fTexFBOID; 867 } 868 869 // below here we may bind the FBO 870 fHWBoundRenderTarget = NULL; 871 if (desc->fRTFBOID != desc->fTexFBOID) { 872 GrAssert(desc->fSampleCnt > 0); 873 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, 874 desc->fMSColorRenderbufferID)); 875 if (!renderbuffer_storage_msaa(fGLContextInfo, 876 desc->fSampleCnt, 877 msColorFormat, 878 width, height)) { 879 goto FAILED; 880 } 881 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fRTFBOID)); 882 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 883 GR_GL_COLOR_ATTACHMENT0, 884 GR_GL_RENDERBUFFER, 885 desc->fMSColorRenderbufferID)); 886 if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) { 887 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 888 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 889 goto FAILED; 890 } 891 fGLContextInfo.caps().markConfigAsValidColorAttachment( 892 desc->fConfig); 893 } 894 } 895 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID)); 896 897 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, 898 GR_GL_COLOR_ATTACHMENT0, 899 GR_GL_TEXTURE_2D, 900 texID, 0)); 901 if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) { 902 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 903 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 904 goto FAILED; 905 } 906 fGLContextInfo.caps().markConfigAsValidColorAttachment(desc->fConfig); 907 } 908 909 return true; 910 911 FAILED: 912 if (desc->fMSColorRenderbufferID) { 913 GL_CALL(DeleteRenderbuffers(1, &desc->fMSColorRenderbufferID)); 914 } 915 if (desc->fRTFBOID != desc->fTexFBOID) { 916 GL_CALL(DeleteFramebuffers(1, &desc->fRTFBOID)); 917 } 918 if (desc->fTexFBOID) { 919 GL_CALL(DeleteFramebuffers(1, &desc->fTexFBOID)); 920 } 921 return false; 922 } 923 924 // good to set a break-point here to know when createTexture fails 925 static GrTexture* return_null_texture() { 926 // GrAssert(!"null texture"); 927 return NULL; 928 } 929 930 #if 0 && GR_DEBUG 931 static size_t as_size_t(int x) { 932 return x; 933 } 934 #endif 935 936 GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc, 937 const void* srcData, 938 size_t rowBytes) { 939 940 GrGLTexture::Desc glTexDesc; 941 GrGLRenderTarget::Desc glRTDesc; 942 943 // Attempt to catch un- or wrongly initialized sample counts; 944 GrAssert(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64); 945 946 glTexDesc.fFlags = desc.fFlags; 947 glTexDesc.fWidth = desc.fWidth; 948 glTexDesc.fHeight = desc.fHeight; 949 glTexDesc.fConfig = desc.fConfig; 950 glTexDesc.fSampleCnt = desc.fSampleCnt; 951 glTexDesc.fIsWrapped = false; 952 953 glRTDesc.fMSColorRenderbufferID = 0; 954 glRTDesc.fRTFBOID = 0; 955 glRTDesc.fTexFBOID = 0; 956 glRTDesc.fIsWrapped = false; 957 glRTDesc.fConfig = glTexDesc.fConfig; 958 959 bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit); 960 961 const Caps& caps = this->getCaps(); 962 963 // We keep GrRenderTargets in GL's normal orientation so that they 964 // can be drawn to by the outside world without the client having 965 // to render upside down. 966 glTexDesc.fOrigin = renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin; 967 968 glRTDesc.fSampleCnt = desc.fSampleCnt; 969 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && 970 desc.fSampleCnt) { 971 //GrPrintf("MSAA RT requested but not supported on this platform."); 972 return return_null_texture(); 973 } 974 975 if (renderTarget) { 976 if (glTexDesc.fWidth > caps.maxRenderTargetSize() || 977 glTexDesc.fHeight > caps.maxRenderTargetSize()) { 978 return return_null_texture(); 979 } 980 } 981 982 GL_CALL(GenTextures(1, &glTexDesc.fTextureID)); 983 if (renderTarget && this->glCaps().textureUsageSupport()) { 984 // provides a hint about how this texture will be used 985 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 986 GR_GL_TEXTURE_USAGE, 987 GR_GL_FRAMEBUFFER_ATTACHMENT)); 988 } 989 if (!glTexDesc.fTextureID) { 990 return return_null_texture(); 991 } 992 993 this->setSpareTextureUnit(); 994 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID)); 995 996 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 997 // drivers have a bug where an FBO won't be complete if it includes a 998 // texture that is not mipmap complete (considering the filter in use). 999 GrGLTexture::TexParams initialTexParams; 1000 // we only set a subset here so invalidate first 1001 initialTexParams.invalidate(); 1002 initialTexParams.fFilter = GR_GL_NEAREST; 1003 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; 1004 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; 1005 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1006 GR_GL_TEXTURE_MAG_FILTER, 1007 initialTexParams.fFilter)); 1008 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1009 GR_GL_TEXTURE_MIN_FILTER, 1010 initialTexParams.fFilter)); 1011 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1012 GR_GL_TEXTURE_WRAP_S, 1013 initialTexParams.fWrapS)); 1014 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1015 GR_GL_TEXTURE_WRAP_T, 1016 initialTexParams.fWrapT)); 1017 if (!this->uploadTexData(glTexDesc, true, 0, 0, 1018 glTexDesc.fWidth, glTexDesc.fHeight, 1019 desc.fConfig, srcData, rowBytes)) { 1020 GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID)); 1021 return return_null_texture(); 1022 } 1023 1024 GrGLTexture* tex; 1025 if (renderTarget) { 1026 // unbind the texture from the texture unit before binding it to the frame buffer 1027 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); 1028 1029 if (!this->createRenderTargetObjects(glTexDesc.fWidth, 1030 glTexDesc.fHeight, 1031 glTexDesc.fTextureID, 1032 &glRTDesc)) { 1033 GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID)); 1034 return return_null_texture(); 1035 } 1036 tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc, glRTDesc)); 1037 } else { 1038 tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc)); 1039 } 1040 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1041 #ifdef TRACE_TEXTURE_CREATION 1042 GrPrintf("--- new texture [%d] size=(%d %d) config=%d\n", 1043 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1044 #endif 1045 return tex; 1046 } 1047 1048 namespace { 1049 1050 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount; 1051 1052 void inline get_stencil_rb_sizes(const GrGLInterface* gl, 1053 GrGLuint rb, 1054 GrGLStencilBuffer::Format* format) { 1055 // we shouldn't ever know one size and not the other 1056 GrAssert((kUnknownBitCount == format->fStencilBits) == 1057 (kUnknownBitCount == format->fTotalBits)); 1058 if (kUnknownBitCount == format->fStencilBits) { 1059 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 1060 GR_GL_RENDERBUFFER_STENCIL_SIZE, 1061 (GrGLint*)&format->fStencilBits); 1062 if (format->fPacked) { 1063 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 1064 GR_GL_RENDERBUFFER_DEPTH_SIZE, 1065 (GrGLint*)&format->fTotalBits); 1066 format->fTotalBits += format->fStencilBits; 1067 } else { 1068 format->fTotalBits = format->fStencilBits; 1069 } 1070 } 1071 } 1072 } 1073 1074 bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, 1075 int width, int height) { 1076 1077 // All internally created RTs are also textures. We don't create 1078 // SBs for a client's standalone RT (that is a RT that isn't also a texture). 1079 GrAssert(rt->asTexture()); 1080 GrAssert(width >= rt->width()); 1081 GrAssert(height >= rt->height()); 1082 1083 int samples = rt->numSamples(); 1084 GrGLuint sbID; 1085 GL_CALL(GenRenderbuffers(1, &sbID)); 1086 if (!sbID) { 1087 return false; 1088 } 1089 1090 int stencilFmtCnt = this->glCaps().stencilFormats().count(); 1091 for (int i = 0; i < stencilFmtCnt; ++i) { 1092 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID)); 1093 // we start with the last stencil format that succeeded in hopes 1094 // that we won't go through this loop more than once after the 1095 // first (painful) stencil creation. 1096 int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt; 1097 const GrGLCaps::StencilFormat& sFmt = 1098 this->glCaps().stencilFormats()[sIdx]; 1099 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1100 // we do this "if" so that we don't call the multisample 1101 // version on a GL that doesn't have an MSAA extension. 1102 bool created; 1103 if (samples > 0) { 1104 created = renderbuffer_storage_msaa(fGLContextInfo, 1105 samples, 1106 sFmt.fInternalFormat, 1107 width, height); 1108 } else { 1109 GL_ALLOC_CALL(this->glInterface(), 1110 RenderbufferStorage(GR_GL_RENDERBUFFER, 1111 sFmt.fInternalFormat, 1112 width, height)); 1113 created = 1114 (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface())); 1115 } 1116 if (created) { 1117 // After sized formats we attempt an unsized format and take 1118 // whatever sizes GL gives us. In that case we query for the size. 1119 GrGLStencilBuffer::Format format = sFmt; 1120 get_stencil_rb_sizes(this->glInterface(), sbID, &format); 1121 static const bool kIsWrapped = false; 1122 SkAutoTUnref<GrStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, 1123 (this, kIsWrapped, sbID, width, height, 1124 samples, format))); 1125 if (this->attachStencilBufferToRenderTarget(sb, rt)) { 1126 fLastSuccessfulStencilFmtIdx = sIdx; 1127 sb->transferToCache(); 1128 rt->setStencilBuffer(sb); 1129 return true; 1130 } 1131 sb->abandon(); // otherwise we lose sbID 1132 } 1133 } 1134 GL_CALL(DeleteRenderbuffers(1, &sbID)); 1135 return false; 1136 } 1137 1138 bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, 1139 GrRenderTarget* rt) { 1140 GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt; 1141 1142 GrGLuint fbo = glrt->renderFBOID(); 1143 1144 if (NULL == sb) { 1145 if (NULL != rt->getStencilBuffer()) { 1146 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1147 GR_GL_STENCIL_ATTACHMENT, 1148 GR_GL_RENDERBUFFER, 0)); 1149 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1150 GR_GL_DEPTH_ATTACHMENT, 1151 GR_GL_RENDERBUFFER, 0)); 1152 #if GR_DEBUG 1153 GrGLenum status; 1154 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1155 GrAssert(GR_GL_FRAMEBUFFER_COMPLETE == status); 1156 #endif 1157 } 1158 return true; 1159 } else { 1160 GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb; 1161 GrGLuint rb = glsb->renderbufferID(); 1162 1163 fHWBoundRenderTarget = NULL; 1164 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); 1165 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1166 GR_GL_STENCIL_ATTACHMENT, 1167 GR_GL_RENDERBUFFER, rb)); 1168 if (glsb->format().fPacked) { 1169 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1170 GR_GL_DEPTH_ATTACHMENT, 1171 GR_GL_RENDERBUFFER, rb)); 1172 } else { 1173 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1174 GR_GL_DEPTH_ATTACHMENT, 1175 GR_GL_RENDERBUFFER, 0)); 1176 } 1177 1178 GrGLenum status; 1179 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(), 1180 glsb->format())) { 1181 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1182 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1183 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1184 GR_GL_STENCIL_ATTACHMENT, 1185 GR_GL_RENDERBUFFER, 0)); 1186 if (glsb->format().fPacked) { 1187 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1188 GR_GL_DEPTH_ATTACHMENT, 1189 GR_GL_RENDERBUFFER, 0)); 1190 } 1191 return false; 1192 } else { 1193 fGLContextInfo.caps().markColorConfigAndStencilFormatAsVerified( 1194 rt->config(), 1195 glsb->format()); 1196 } 1197 } 1198 return true; 1199 } 1200 } 1201 1202 //////////////////////////////////////////////////////////////////////////////// 1203 1204 GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) { 1205 GrGLuint id; 1206 GL_CALL(GenBuffers(1, &id)); 1207 if (id) { 1208 GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, id)); 1209 fHWGeometryState.fArrayPtrsDirty = true; 1210 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1211 // make sure driver can allocate memory for this buffer 1212 GL_ALLOC_CALL(this->glInterface(), 1213 BufferData(GR_GL_ARRAY_BUFFER, 1214 size, 1215 NULL, // data ptr 1216 dynamic ? GR_GL_DYNAMIC_DRAW : 1217 GR_GL_STATIC_DRAW)); 1218 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) { 1219 GL_CALL(DeleteBuffers(1, &id)); 1220 // deleting bound buffer does implicit bind to 0 1221 fHWGeometryState.fVertexBuffer = NULL; 1222 return NULL; 1223 } 1224 static const bool kIsWrapped = false; 1225 GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, 1226 (this, kIsWrapped, id, 1227 size, dynamic)); 1228 fHWGeometryState.fVertexBuffer = vertexBuffer; 1229 return vertexBuffer; 1230 } 1231 return NULL; 1232 } 1233 1234 GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) { 1235 GrGLuint id; 1236 GL_CALL(GenBuffers(1, &id)); 1237 if (id) { 1238 GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id)); 1239 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1240 // make sure driver can allocate memory for this buffer 1241 GL_ALLOC_CALL(this->glInterface(), 1242 BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, 1243 size, 1244 NULL, // data ptr 1245 dynamic ? GR_GL_DYNAMIC_DRAW : 1246 GR_GL_STATIC_DRAW)); 1247 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) { 1248 GL_CALL(DeleteBuffers(1, &id)); 1249 // deleting bound buffer does implicit bind to 0 1250 fHWGeometryState.fIndexBuffer = NULL; 1251 return NULL; 1252 } 1253 static const bool kIsWrapped = false; 1254 GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, 1255 (this, kIsWrapped, id, size, dynamic)); 1256 fHWGeometryState.fIndexBuffer = indexBuffer; 1257 return indexBuffer; 1258 } 1259 return NULL; 1260 } 1261 1262 GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) { 1263 GrAssert(fCaps.pathStencilingSupport()); 1264 return SkNEW_ARGS(GrGLPath, (this, inPath)); 1265 } 1266 1267 void GrGpuGL::flushScissor() { 1268 const GrDrawState& drawState = this->getDrawState(); 1269 const GrGLRenderTarget* rt = 1270 static_cast<const GrGLRenderTarget*>(drawState.getRenderTarget()); 1271 1272 GrAssert(NULL != rt); 1273 const GrGLIRect& vp = rt->getViewport(); 1274 1275 if (fScissorState.fEnabled) { 1276 GrGLIRect scissor; 1277 scissor.setRelativeTo(vp, 1278 fScissorState.fRect.fLeft, 1279 fScissorState.fRect.fTop, 1280 fScissorState.fRect.width(), 1281 fScissorState.fRect.height()); 1282 // if the scissor fully contains the viewport then we fall through and 1283 // disable the scissor test. 1284 if (!scissor.contains(vp)) { 1285 if (fHWScissorSettings.fRect != scissor) { 1286 scissor.pushToGLScissor(this->glInterface()); 1287 fHWScissorSettings.fRect = scissor; 1288 } 1289 if (kYes_TriState != fHWScissorSettings.fEnabled) { 1290 GL_CALL(Enable(GR_GL_SCISSOR_TEST)); 1291 fHWScissorSettings.fEnabled = kYes_TriState; 1292 } 1293 return; 1294 } 1295 } 1296 if (kNo_TriState != fHWScissorSettings.fEnabled) { 1297 GL_CALL(Disable(GR_GL_SCISSOR_TEST)); 1298 fHWScissorSettings.fEnabled = kNo_TriState; 1299 return; 1300 } 1301 } 1302 1303 void GrGpuGL::onClear(const GrIRect* rect, GrColor color) { 1304 const GrDrawState& drawState = this->getDrawState(); 1305 const GrRenderTarget* rt = drawState.getRenderTarget(); 1306 // parent class should never let us get here with no RT 1307 GrAssert(NULL != rt); 1308 1309 GrIRect clippedRect; 1310 if (NULL != rect) { 1311 // flushScissor expects rect to be clipped to the target. 1312 clippedRect = *rect; 1313 GrIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height()); 1314 if (clippedRect.intersect(rtRect)) { 1315 rect = &clippedRect; 1316 } else { 1317 return; 1318 } 1319 } 1320 this->flushRenderTarget(rect); 1321 GrAutoTRestore<ScissorState> asr(&fScissorState); 1322 fScissorState.fEnabled = (NULL != rect); 1323 if (fScissorState.fEnabled) { 1324 fScissorState.fRect = *rect; 1325 } 1326 this->flushScissor(); 1327 1328 GrGLfloat r, g, b, a; 1329 static const GrGLfloat scale255 = 1.f / 255.f; 1330 a = GrColorUnpackA(color) * scale255; 1331 GrGLfloat scaleRGB = scale255; 1332 r = GrColorUnpackR(color) * scaleRGB; 1333 g = GrColorUnpackG(color) * scaleRGB; 1334 b = GrColorUnpackB(color) * scaleRGB; 1335 1336 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 1337 fHWWriteToColor = kYes_TriState; 1338 GL_CALL(ClearColor(r, g, b, a)); 1339 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); 1340 } 1341 1342 void GrGpuGL::clearStencil() { 1343 if (NULL == this->getDrawState().getRenderTarget()) { 1344 return; 1345 } 1346 1347 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1348 1349 GrAutoTRestore<ScissorState> asr(&fScissorState); 1350 fScissorState.fEnabled = false; 1351 this->flushScissor(); 1352 1353 GL_CALL(StencilMask(0xffffffff)); 1354 GL_CALL(ClearStencil(0)); 1355 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 1356 fHWStencilSettings.invalidate(); 1357 } 1358 1359 void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) { 1360 const GrDrawState& drawState = this->getDrawState(); 1361 const GrRenderTarget* rt = drawState.getRenderTarget(); 1362 GrAssert(NULL != rt); 1363 1364 // this should only be called internally when we know we have a 1365 // stencil buffer. 1366 GrAssert(NULL != rt->getStencilBuffer()); 1367 GrGLint stencilBitCount = rt->getStencilBuffer()->bits(); 1368 #if 0 1369 GrAssert(stencilBitCount > 0); 1370 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); 1371 #else 1372 // we could just clear the clip bit but when we go through 1373 // ANGLE a partial stencil mask will cause clears to be 1374 // turned into draws. Our contract on GrDrawTarget says that 1375 // changing the clip between stencil passes may or may not 1376 // zero the client's clip bits. So we just clear the whole thing. 1377 static const GrGLint clipStencilMask = ~0; 1378 #endif 1379 GrGLint value; 1380 if (insideClip) { 1381 value = (1 << (stencilBitCount - 1)); 1382 } else { 1383 value = 0; 1384 } 1385 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1386 1387 GrAutoTRestore<ScissorState> asr(&fScissorState); 1388 fScissorState.fEnabled = true; 1389 fScissorState.fRect = rect; 1390 this->flushScissor(); 1391 1392 GL_CALL(StencilMask((uint32_t) clipStencilMask)); 1393 GL_CALL(ClearStencil(value)); 1394 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 1395 fHWStencilSettings.invalidate(); 1396 } 1397 1398 void GrGpuGL::onForceRenderTargetFlush() { 1399 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1400 } 1401 1402 bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget, 1403 int left, int top, 1404 int width, int height, 1405 GrPixelConfig config, 1406 size_t rowBytes) const { 1407 // if GL can do the flip then we'll never pay for it. 1408 if (this->glCaps().packFlipYSupport()) { 1409 return false; 1410 } 1411 1412 // If we have to do memcpy to handle non-trim rowBytes then we 1413 // get the flip for free. Otherwise it costs. 1414 if (this->glCaps().packRowLengthSupport()) { 1415 return true; 1416 } 1417 // If we have to do memcpys to handle rowBytes then y-flip is free 1418 // Note the rowBytes might be tight to the passed in data, but if data 1419 // gets clipped in x to the target the rowBytes will no longer be tight. 1420 if (left >= 0 && (left + width) < renderTarget->width()) { 1421 return 0 == rowBytes || 1422 GrBytesPerPixel(config) * width == rowBytes; 1423 } else { 1424 return false; 1425 } 1426 } 1427 1428 bool GrGpuGL::onReadPixels(GrRenderTarget* target, 1429 int left, int top, 1430 int width, int height, 1431 GrPixelConfig config, 1432 void* buffer, 1433 size_t rowBytes, 1434 bool invertY) { 1435 GrGLenum format; 1436 GrGLenum type; 1437 if (!this->configToGLFormats(config, false, NULL, &format, &type)) { 1438 return false; 1439 } 1440 size_t bpp = GrBytesPerPixel(config); 1441 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, 1442 &left, &top, &width, &height, 1443 const_cast<const void**>(&buffer), 1444 &rowBytes)) { 1445 return false; 1446 } 1447 1448 // resolve the render target if necessary 1449 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); 1450 GrDrawState::AutoRenderTargetRestore artr; 1451 switch (tgt->getResolveType()) { 1452 case GrGLRenderTarget::kCantResolve_ResolveType: 1453 return false; 1454 case GrGLRenderTarget::kAutoResolves_ResolveType: 1455 artr.set(this->drawState(), target); 1456 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1457 break; 1458 case GrGLRenderTarget::kCanResolve_ResolveType: 1459 this->onResolveRenderTarget(tgt); 1460 // we don't track the state of the READ FBO ID. 1461 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, 1462 tgt->textureFBOID())); 1463 break; 1464 default: 1465 GrCrash("Unknown resolve type"); 1466 } 1467 1468 const GrGLIRect& glvp = tgt->getViewport(); 1469 1470 // the read rect is viewport-relative 1471 GrGLIRect readRect; 1472 readRect.setRelativeTo(glvp, left, top, width, height); 1473 1474 size_t tightRowBytes = bpp * width; 1475 if (0 == rowBytes) { 1476 rowBytes = tightRowBytes; 1477 } 1478 size_t readDstRowBytes = tightRowBytes; 1479 void* readDst = buffer; 1480 1481 // determine if GL can read using the passed rowBytes or if we need 1482 // a scratch buffer. 1483 SkAutoSMalloc<32 * sizeof(GrColor)> scratch; 1484 if (rowBytes != tightRowBytes) { 1485 if (this->glCaps().packRowLengthSupport()) { 1486 GrAssert(!(rowBytes % sizeof(GrColor))); 1487 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowBytes / sizeof(GrColor))); 1488 readDstRowBytes = rowBytes; 1489 } else { 1490 scratch.reset(tightRowBytes * height); 1491 readDst = scratch.get(); 1492 } 1493 } 1494 if (!invertY && this->glCaps().packFlipYSupport()) { 1495 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1)); 1496 } 1497 GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom, 1498 readRect.fWidth, readRect.fHeight, 1499 format, type, readDst)); 1500 if (readDstRowBytes != tightRowBytes) { 1501 GrAssert(this->glCaps().packRowLengthSupport()); 1502 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 1503 } 1504 if (!invertY && this->glCaps().packFlipYSupport()) { 1505 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0)); 1506 invertY = true; 1507 } 1508 1509 // now reverse the order of the rows, since GL's are bottom-to-top, but our 1510 // API presents top-to-bottom. We must preserve the padding contents. Note 1511 // that the above readPixels did not overwrite the padding. 1512 if (readDst == buffer) { 1513 GrAssert(rowBytes == readDstRowBytes); 1514 if (!invertY) { 1515 scratch.reset(tightRowBytes); 1516 void* tmpRow = scratch.get(); 1517 // flip y in-place by rows 1518 const int halfY = height >> 1; 1519 char* top = reinterpret_cast<char*>(buffer); 1520 char* bottom = top + (height - 1) * rowBytes; 1521 for (int y = 0; y < halfY; y++) { 1522 memcpy(tmpRow, top, tightRowBytes); 1523 memcpy(top, bottom, tightRowBytes); 1524 memcpy(bottom, tmpRow, tightRowBytes); 1525 top += rowBytes; 1526 bottom -= rowBytes; 1527 } 1528 } 1529 } else { 1530 GrAssert(readDst != buffer); GrAssert(rowBytes != tightRowBytes); 1531 // copy from readDst to buffer while flipping y 1532 // const int halfY = height >> 1; 1533 const char* src = reinterpret_cast<const char*>(readDst); 1534 char* dst = reinterpret_cast<char*>(buffer); 1535 if (!invertY) { 1536 dst += (height-1) * rowBytes; 1537 } 1538 for (int y = 0; y < height; y++) { 1539 memcpy(dst, src, tightRowBytes); 1540 src += readDstRowBytes; 1541 if (invertY) { 1542 dst += rowBytes; 1543 } else { 1544 dst -= rowBytes; 1545 } 1546 } 1547 } 1548 return true; 1549 } 1550 1551 void GrGpuGL::flushRenderTarget(const GrIRect* bound) { 1552 1553 GrGLRenderTarget* rt = 1554 static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget()); 1555 GrAssert(NULL != rt); 1556 1557 if (fHWBoundRenderTarget != rt) { 1558 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID())); 1559 #if GR_DEBUG 1560 GrGLenum status; 1561 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1562 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1563 GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status); 1564 } 1565 #endif 1566 fHWBoundRenderTarget = rt; 1567 const GrGLIRect& vp = rt->getViewport(); 1568 if (fHWViewport != vp) { 1569 vp.pushToGLViewport(this->glInterface()); 1570 fHWViewport = vp; 1571 } 1572 } 1573 if (NULL == bound || !bound->isEmpty()) { 1574 rt->flagAsNeedingResolve(bound); 1575 } 1576 } 1577 1578 GrGLenum gPrimitiveType2GLMode[] = { 1579 GR_GL_TRIANGLES, 1580 GR_GL_TRIANGLE_STRIP, 1581 GR_GL_TRIANGLE_FAN, 1582 GR_GL_POINTS, 1583 GR_GL_LINES, 1584 GR_GL_LINE_STRIP 1585 }; 1586 1587 #define SWAP_PER_DRAW 0 1588 1589 #if SWAP_PER_DRAW 1590 #if GR_MAC_BUILD 1591 #include <AGL/agl.h> 1592 #elif GR_WIN32_BUILD 1593 #include <gl/GL.h> 1594 void SwapBuf() { 1595 DWORD procID = GetCurrentProcessId(); 1596 HWND hwnd = GetTopWindow(GetDesktopWindow()); 1597 while(hwnd) { 1598 DWORD wndProcID = 0; 1599 GetWindowThreadProcessId(hwnd, &wndProcID); 1600 if(wndProcID == procID) { 1601 SwapBuffers(GetDC(hwnd)); 1602 } 1603 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); 1604 } 1605 } 1606 #endif 1607 #endif 1608 1609 void GrGpuGL::onGpuDraw(const DrawInfo& info) { 1610 int extraStartIndexOffset; 1611 this->setupGeometry(info, &extraStartIndexOffset); 1612 1613 GrAssert((size_t)info.primitiveType() < GR_ARRAY_COUNT(gPrimitiveType2GLMode)); 1614 GrAssert(NULL != fHWGeometryState.fVertexBuffer); 1615 1616 if (info.isIndexed()) { 1617 GrAssert(NULL != fHWGeometryState.fIndexBuffer); 1618 GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * (info.startIndex() + 1619 extraStartIndexOffset)); 1620 // info.startVertex() was accounted for by setupGeometry. 1621 GL_CALL(DrawElements(gPrimitiveType2GLMode[info.primitiveType()], 1622 info.indexCount(), 1623 GR_GL_UNSIGNED_SHORT, 1624 indices)); 1625 } else { 1626 // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for 1627 // startVertex in the DrawElements case. So we always rely on setupGeometry to have 1628 // accounted for startVertex. 1629 GL_CALL(DrawArrays(gPrimitiveType2GLMode[info.primitiveType()], 0, info.vertexCount())); 1630 } 1631 #if SWAP_PER_DRAW 1632 glFlush(); 1633 #if GR_MAC_BUILD 1634 aglSwapBuffers(aglGetCurrentContext()); 1635 int set_a_break_pt_here = 9; 1636 aglSwapBuffers(aglGetCurrentContext()); 1637 #elif GR_WIN32_BUILD 1638 SwapBuf(); 1639 int set_a_break_pt_here = 9; 1640 SwapBuf(); 1641 #endif 1642 #endif 1643 } 1644 1645 namespace { 1646 1647 static const uint16_t kOnes16 = static_cast<uint16_t>(~0); 1648 const GrStencilSettings& winding_nv_path_stencil_settings() { 1649 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, 1650 kIncClamp_StencilOp, 1651 kIncClamp_StencilOp, 1652 kAlwaysIfInClip_StencilFunc, 1653 kOnes16, kOnes16, kOnes16); 1654 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 1655 } 1656 const GrStencilSettings& even_odd_nv_path_stencil_settings() { 1657 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, 1658 kInvert_StencilOp, 1659 kInvert_StencilOp, 1660 kAlwaysIfInClip_StencilFunc, 1661 kOnes16, kOnes16, kOnes16); 1662 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 1663 } 1664 } 1665 1666 void GrGpuGL::setStencilPathSettings(const GrPath&, 1667 SkPath::FillType fill, 1668 GrStencilSettings* settings) { 1669 switch (fill) { 1670 case SkPath::kEvenOdd_FillType: 1671 *settings = even_odd_nv_path_stencil_settings(); 1672 return; 1673 case SkPath::kWinding_FillType: 1674 *settings = winding_nv_path_stencil_settings(); 1675 return; 1676 default: 1677 GrCrash("Unexpected path fill."); 1678 } 1679 } 1680 1681 void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { 1682 GrAssert(fCaps.pathStencilingSupport()); 1683 1684 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 1685 GrDrawState* drawState = this->drawState(); 1686 GrAssert(NULL != drawState->getRenderTarget()); 1687 if (NULL == drawState->getRenderTarget()->getStencilBuffer()) { 1688 return; 1689 } 1690 1691 // Decide how to manipulate the stencil buffer based on the fill rule. 1692 // Also, assert that the stencil settings we set in setStencilPathSettings 1693 // are present. 1694 GrAssert(!fStencilSettings.isTwoSided()); 1695 GrGLenum fillMode; 1696 switch (fill) { 1697 case SkPath::kWinding_FillType: 1698 fillMode = GR_GL_COUNT_UP; 1699 GrAssert(kIncClamp_StencilOp == 1700 fStencilSettings.passOp(GrStencilSettings::kFront_Face)); 1701 GrAssert(kIncClamp_StencilOp == 1702 fStencilSettings.failOp(GrStencilSettings::kFront_Face)); 1703 break; 1704 case SkPath::kEvenOdd_FillType: 1705 fillMode = GR_GL_INVERT; 1706 GrAssert(kInvert_StencilOp == 1707 fStencilSettings.passOp(GrStencilSettings::kFront_Face)); 1708 GrAssert(kInvert_StencilOp == 1709 fStencilSettings.failOp(GrStencilSettings::kFront_Face)); 1710 break; 1711 default: 1712 // Only the above two fill rules are allowed. 1713 GrCrash("Unexpected path fill."); 1714 return; // suppress unused var warning. 1715 } 1716 GrGLint writeMask = fStencilSettings.writeMask(GrStencilSettings::kFront_Face); 1717 GL_CALL(StencilFillPath(id, fillMode, writeMask)); 1718 } 1719 1720 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) { 1721 1722 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); 1723 1724 if (rt->needsResolve()) { 1725 GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType()); 1726 GrAssert(rt->textureFBOID() != rt->renderFBOID()); 1727 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, 1728 rt->renderFBOID())); 1729 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, 1730 rt->textureFBOID())); 1731 // make sure we go through flushRenderTarget() since we've modified 1732 // the bound DRAW FBO ID. 1733 fHWBoundRenderTarget = NULL; 1734 const GrGLIRect& vp = rt->getViewport(); 1735 const GrIRect dirtyRect = rt->getResolveRect(); 1736 GrGLIRect r; 1737 r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop, 1738 dirtyRect.width(), dirtyRect.height()); 1739 1740 GrAutoTRestore<ScissorState> asr; 1741 if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) { 1742 // Apple's extension uses the scissor as the blit bounds. 1743 asr.reset(&fScissorState); 1744 fScissorState.fEnabled = true; 1745 fScissorState.fRect = dirtyRect; 1746 this->flushScissor(); 1747 GL_CALL(ResolveMultisampleFramebuffer()); 1748 } else { 1749 if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) { 1750 // this respects the scissor during the blit, so disable it. 1751 GrAssert(GrGLCaps::kDesktopEXT_MSFBOType == 1752 this->glCaps().msFBOType()); 1753 asr.reset(&fScissorState); 1754 fScissorState.fEnabled = false; 1755 this->flushScissor(); 1756 } 1757 int right = r.fLeft + r.fWidth; 1758 int top = r.fBottom + r.fHeight; 1759 GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top, 1760 r.fLeft, r.fBottom, right, top, 1761 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 1762 } 1763 rt->flagAsResolved(); 1764 } 1765 } 1766 1767 namespace { 1768 1769 GrGLenum gr_to_gl_stencil_func(GrStencilFunc basicFunc) { 1770 static const GrGLenum gTable[] = { 1771 GR_GL_ALWAYS, // kAlways_StencilFunc 1772 GR_GL_NEVER, // kNever_StencilFunc 1773 GR_GL_GREATER, // kGreater_StencilFunc 1774 GR_GL_GEQUAL, // kGEqual_StencilFunc 1775 GR_GL_LESS, // kLess_StencilFunc 1776 GR_GL_LEQUAL, // kLEqual_StencilFunc, 1777 GR_GL_EQUAL, // kEqual_StencilFunc, 1778 GR_GL_NOTEQUAL, // kNotEqual_StencilFunc, 1779 }; 1780 GR_STATIC_ASSERT(GR_ARRAY_COUNT(gTable) == kBasicStencilFuncCount); 1781 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); 1782 GR_STATIC_ASSERT(1 == kNever_StencilFunc); 1783 GR_STATIC_ASSERT(2 == kGreater_StencilFunc); 1784 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc); 1785 GR_STATIC_ASSERT(4 == kLess_StencilFunc); 1786 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc); 1787 GR_STATIC_ASSERT(6 == kEqual_StencilFunc); 1788 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc); 1789 GrAssert((unsigned) basicFunc < kBasicStencilFuncCount); 1790 1791 return gTable[basicFunc]; 1792 } 1793 1794 GrGLenum gr_to_gl_stencil_op(GrStencilOp op) { 1795 static const GrGLenum gTable[] = { 1796 GR_GL_KEEP, // kKeep_StencilOp 1797 GR_GL_REPLACE, // kReplace_StencilOp 1798 GR_GL_INCR_WRAP, // kIncWrap_StencilOp 1799 GR_GL_INCR, // kIncClamp_StencilOp 1800 GR_GL_DECR_WRAP, // kDecWrap_StencilOp 1801 GR_GL_DECR, // kDecClamp_StencilOp 1802 GR_GL_ZERO, // kZero_StencilOp 1803 GR_GL_INVERT, // kInvert_StencilOp 1804 }; 1805 GR_STATIC_ASSERT(GR_ARRAY_COUNT(gTable) == kStencilOpCount); 1806 GR_STATIC_ASSERT(0 == kKeep_StencilOp); 1807 GR_STATIC_ASSERT(1 == kReplace_StencilOp); 1808 GR_STATIC_ASSERT(2 == kIncWrap_StencilOp); 1809 GR_STATIC_ASSERT(3 == kIncClamp_StencilOp); 1810 GR_STATIC_ASSERT(4 == kDecWrap_StencilOp); 1811 GR_STATIC_ASSERT(5 == kDecClamp_StencilOp); 1812 GR_STATIC_ASSERT(6 == kZero_StencilOp); 1813 GR_STATIC_ASSERT(7 == kInvert_StencilOp); 1814 GrAssert((unsigned) op < kStencilOpCount); 1815 return gTable[op]; 1816 } 1817 1818 void set_gl_stencil(const GrGLInterface* gl, 1819 const GrStencilSettings& settings, 1820 GrGLenum glFace, 1821 GrStencilSettings::Face grFace) { 1822 GrGLenum glFunc = gr_to_gl_stencil_func(settings.func(grFace)); 1823 GrGLenum glFailOp = gr_to_gl_stencil_op(settings.failOp(grFace)); 1824 GrGLenum glPassOp = gr_to_gl_stencil_op(settings.passOp(grFace)); 1825 1826 GrGLint ref = settings.funcRef(grFace); 1827 GrGLint mask = settings.funcMask(grFace); 1828 GrGLint writeMask = settings.writeMask(grFace); 1829 1830 if (GR_GL_FRONT_AND_BACK == glFace) { 1831 // we call the combined func just in case separate stencil is not 1832 // supported. 1833 GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask)); 1834 GR_GL_CALL(gl, StencilMask(writeMask)); 1835 GR_GL_CALL(gl, StencilOp(glFailOp, glPassOp, glPassOp)); 1836 } else { 1837 GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask)); 1838 GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask)); 1839 GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, glPassOp, glPassOp)); 1840 } 1841 } 1842 } 1843 1844 void GrGpuGL::flushStencil(DrawType type) { 1845 if (kStencilPath_DrawType == type) { 1846 GrAssert(!fStencilSettings.isTwoSided()); 1847 // Just the func, ref, and mask is set here. The op and write mask are params to the call 1848 // that draws the path to the SB (glStencilFillPath) 1849 GrGLenum func = 1850 gr_to_gl_stencil_func(fStencilSettings.func(GrStencilSettings::kFront_Face)); 1851 GL_CALL(PathStencilFunc(func, 1852 fStencilSettings.funcRef(GrStencilSettings::kFront_Face), 1853 fStencilSettings.funcMask(GrStencilSettings::kFront_Face))); 1854 } else if (fHWStencilSettings != fStencilSettings) { 1855 if (fStencilSettings.isDisabled()) { 1856 if (kNo_TriState != fHWStencilTestEnabled) { 1857 GL_CALL(Disable(GR_GL_STENCIL_TEST)); 1858 fHWStencilTestEnabled = kNo_TriState; 1859 } 1860 } else { 1861 if (kYes_TriState != fHWStencilTestEnabled) { 1862 GL_CALL(Enable(GR_GL_STENCIL_TEST)); 1863 fHWStencilTestEnabled = kYes_TriState; 1864 } 1865 } 1866 if (!fStencilSettings.isDisabled()) { 1867 if (this->getCaps().twoSidedStencilSupport()) { 1868 set_gl_stencil(this->glInterface(), 1869 fStencilSettings, 1870 GR_GL_FRONT, 1871 GrStencilSettings::kFront_Face); 1872 set_gl_stencil(this->glInterface(), 1873 fStencilSettings, 1874 GR_GL_BACK, 1875 GrStencilSettings::kBack_Face); 1876 } else { 1877 set_gl_stencil(this->glInterface(), 1878 fStencilSettings, 1879 GR_GL_FRONT_AND_BACK, 1880 GrStencilSettings::kFront_Face); 1881 } 1882 } 1883 fHWStencilSettings = fStencilSettings; 1884 } 1885 } 1886 1887 void GrGpuGL::flushAAState(DrawType type) { 1888 const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); 1889 if (kDesktop_GrGLBinding == this->glBinding()) { 1890 // ES doesn't support toggling GL_MULTISAMPLE and doesn't have 1891 // smooth lines. 1892 // we prefer smooth lines over multisampled lines 1893 bool smoothLines = false; 1894 1895 if (kDrawLines_DrawType == type) { 1896 smoothLines = this->willUseHWAALines(); 1897 if (smoothLines) { 1898 if (kYes_TriState != fHWAAState.fSmoothLineEnabled) { 1899 GL_CALL(Enable(GR_GL_LINE_SMOOTH)); 1900 fHWAAState.fSmoothLineEnabled = kYes_TriState; 1901 // must disable msaa to use line smoothing 1902 if (rt->isMultisampled() && 1903 kNo_TriState != fHWAAState.fMSAAEnabled) { 1904 GL_CALL(Disable(GR_GL_MULTISAMPLE)); 1905 fHWAAState.fMSAAEnabled = kNo_TriState; 1906 } 1907 } 1908 } else { 1909 if (kNo_TriState != fHWAAState.fSmoothLineEnabled) { 1910 GL_CALL(Disable(GR_GL_LINE_SMOOTH)); 1911 fHWAAState.fSmoothLineEnabled = kNo_TriState; 1912 } 1913 } 1914 } 1915 if (!smoothLines && rt->isMultisampled()) { 1916 // FIXME: GL_NV_pr doesn't seem to like MSAA disabled. The paths 1917 // convex hulls of each segment appear to get filled. 1918 bool enableMSAA = kStencilPath_DrawType == type || 1919 this->getDrawState().isHWAntialiasState(); 1920 if (enableMSAA) { 1921 if (kYes_TriState != fHWAAState.fMSAAEnabled) { 1922 GL_CALL(Enable(GR_GL_MULTISAMPLE)); 1923 fHWAAState.fMSAAEnabled = kYes_TriState; 1924 } 1925 } else { 1926 if (kNo_TriState != fHWAAState.fMSAAEnabled) { 1927 GL_CALL(Disable(GR_GL_MULTISAMPLE)); 1928 fHWAAState.fMSAAEnabled = kNo_TriState; 1929 } 1930 } 1931 } 1932 } 1933 } 1934 1935 void GrGpuGL::flushBlend(bool isLines, 1936 GrBlendCoeff srcCoeff, 1937 GrBlendCoeff dstCoeff) { 1938 if (isLines && this->willUseHWAALines()) { 1939 if (kYes_TriState != fHWBlendState.fEnabled) { 1940 GL_CALL(Enable(GR_GL_BLEND)); 1941 fHWBlendState.fEnabled = kYes_TriState; 1942 } 1943 if (kSA_GrBlendCoeff != fHWBlendState.fSrcCoeff || 1944 kISA_GrBlendCoeff != fHWBlendState.fDstCoeff) { 1945 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_GrBlendCoeff], 1946 gXfermodeCoeff2Blend[kISA_GrBlendCoeff])); 1947 fHWBlendState.fSrcCoeff = kSA_GrBlendCoeff; 1948 fHWBlendState.fDstCoeff = kISA_GrBlendCoeff; 1949 } 1950 } else { 1951 // any optimization to disable blending should 1952 // have already been applied and tweaked the coeffs 1953 // to (1, 0). 1954 bool blendOff = kOne_GrBlendCoeff == srcCoeff && 1955 kZero_GrBlendCoeff == dstCoeff; 1956 if (blendOff) { 1957 if (kNo_TriState != fHWBlendState.fEnabled) { 1958 GL_CALL(Disable(GR_GL_BLEND)); 1959 fHWBlendState.fEnabled = kNo_TriState; 1960 } 1961 } else { 1962 if (kYes_TriState != fHWBlendState.fEnabled) { 1963 GL_CALL(Enable(GR_GL_BLEND)); 1964 fHWBlendState.fEnabled = kYes_TriState; 1965 } 1966 if (fHWBlendState.fSrcCoeff != srcCoeff || 1967 fHWBlendState.fDstCoeff != dstCoeff) { 1968 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], 1969 gXfermodeCoeff2Blend[dstCoeff])); 1970 fHWBlendState.fSrcCoeff = srcCoeff; 1971 fHWBlendState.fDstCoeff = dstCoeff; 1972 } 1973 GrColor blendConst = this->getDrawState().getBlendConstant(); 1974 if ((BlendCoeffReferencesConstant(srcCoeff) || 1975 BlendCoeffReferencesConstant(dstCoeff)) && 1976 (!fHWBlendState.fConstColorValid || 1977 fHWBlendState.fConstColor != blendConst)) { 1978 GrGLfloat c[4]; 1979 GrColorToRGBAFloat(blendConst, c); 1980 GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); 1981 fHWBlendState.fConstColor = blendConst; 1982 fHWBlendState.fConstColorValid = true; 1983 } 1984 } 1985 } 1986 } 1987 namespace { 1988 1989 inline void set_tex_swizzle(GrGLenum swizzle[4], const GrGLInterface* gl) { 1990 GR_GL_CALL(gl, TexParameteriv(GR_GL_TEXTURE_2D, 1991 GR_GL_TEXTURE_SWIZZLE_RGBA, 1992 reinterpret_cast<const GrGLint*>(swizzle))); 1993 } 1994 1995 inline GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) { 1996 static const GrGLenum gWrapModes[] = { 1997 GR_GL_CLAMP_TO_EDGE, 1998 GR_GL_REPEAT, 1999 GR_GL_MIRRORED_REPEAT 2000 }; 2001 GrAssert((unsigned) tm <= SK_ARRAY_COUNT(gWrapModes)); 2002 GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode); 2003 GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode); 2004 GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode); 2005 return gWrapModes[tm]; 2006 } 2007 2008 } 2009 2010 void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture) { 2011 GrAssert(NULL != texture); 2012 2013 // If we created a rt/tex and rendered to it without using a texture and now we're texturing 2014 // from the rt it will still be the last bound texture, but it needs resolving. So keep this 2015 // out of the "last != next" check. 2016 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget()); 2017 if (NULL != texRT) { 2018 this->onResolveRenderTarget(texRT); 2019 } 2020 2021 if (fHWBoundTextures[unitIdx] != texture) { 2022 this->setTextureUnit(unitIdx); 2023 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID())); 2024 fHWBoundTextures[unitIdx] = texture; 2025 } 2026 2027 ResetTimestamp timestamp; 2028 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(×tamp); 2029 bool setAll = timestamp < this->getResetTimestamp(); 2030 GrGLTexture::TexParams newTexParams; 2031 2032 newTexParams.fFilter = params.isBilerp() ? GR_GL_LINEAR : GR_GL_NEAREST; 2033 2034 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); 2035 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); 2036 memcpy(newTexParams.fSwizzleRGBA, 2037 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps()), 2038 sizeof(newTexParams.fSwizzleRGBA)); 2039 if (setAll || newTexParams.fFilter != oldTexParams.fFilter) { 2040 this->setTextureUnit(unitIdx); 2041 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2042 GR_GL_TEXTURE_MAG_FILTER, 2043 newTexParams.fFilter)); 2044 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2045 GR_GL_TEXTURE_MIN_FILTER, 2046 newTexParams.fFilter)); 2047 } 2048 if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { 2049 this->setTextureUnit(unitIdx); 2050 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2051 GR_GL_TEXTURE_WRAP_S, 2052 newTexParams.fWrapS)); 2053 } 2054 if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { 2055 this->setTextureUnit(unitIdx); 2056 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2057 GR_GL_TEXTURE_WRAP_T, 2058 newTexParams.fWrapT)); 2059 } 2060 if (this->glCaps().textureSwizzleSupport() && 2061 (setAll || memcmp(newTexParams.fSwizzleRGBA, 2062 oldTexParams.fSwizzleRGBA, 2063 sizeof(newTexParams.fSwizzleRGBA)))) { 2064 this->setTextureUnit(unitIdx); 2065 set_tex_swizzle(newTexParams.fSwizzleRGBA, 2066 this->glInterface()); 2067 } 2068 texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); 2069 } 2070 2071 void GrGpuGL::flushMiscFixedFunctionState() { 2072 2073 const GrDrawState& drawState = this->getDrawState(); 2074 2075 if (drawState.isDitherState()) { 2076 if (kYes_TriState != fHWDitherEnabled) { 2077 GL_CALL(Enable(GR_GL_DITHER)); 2078 fHWDitherEnabled = kYes_TriState; 2079 } 2080 } else { 2081 if (kNo_TriState != fHWDitherEnabled) { 2082 GL_CALL(Disable(GR_GL_DITHER)); 2083 fHWDitherEnabled = kNo_TriState; 2084 } 2085 } 2086 2087 if (drawState.isColorWriteDisabled()) { 2088 if (kNo_TriState != fHWWriteToColor) { 2089 GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE, 2090 GR_GL_FALSE, GR_GL_FALSE)); 2091 fHWWriteToColor = kNo_TriState; 2092 } 2093 } else { 2094 if (kYes_TriState != fHWWriteToColor) { 2095 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 2096 fHWWriteToColor = kYes_TriState; 2097 } 2098 } 2099 2100 if (fHWDrawFace != drawState.getDrawFace()) { 2101 switch (this->getDrawState().getDrawFace()) { 2102 case GrDrawState::kCCW_DrawFace: 2103 GL_CALL(Enable(GR_GL_CULL_FACE)); 2104 GL_CALL(CullFace(GR_GL_BACK)); 2105 break; 2106 case GrDrawState::kCW_DrawFace: 2107 GL_CALL(Enable(GR_GL_CULL_FACE)); 2108 GL_CALL(CullFace(GR_GL_FRONT)); 2109 break; 2110 case GrDrawState::kBoth_DrawFace: 2111 GL_CALL(Disable(GR_GL_CULL_FACE)); 2112 break; 2113 default: 2114 GrCrash("Unknown draw face."); 2115 } 2116 fHWDrawFace = drawState.getDrawFace(); 2117 } 2118 } 2119 2120 void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) { 2121 if (fHWGeometryState.fVertexBuffer != buffer) { 2122 fHWGeometryState.fArrayPtrsDirty = true; 2123 fHWGeometryState.fVertexBuffer = buffer; 2124 } 2125 } 2126 2127 void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) { 2128 if (fHWGeometryState.fVertexBuffer == buffer) { 2129 // deleting bound buffer does implied bind to 0 2130 fHWGeometryState.fVertexBuffer = NULL; 2131 fHWGeometryState.fArrayPtrsDirty = true; 2132 } 2133 } 2134 2135 void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) { 2136 fHWGeometryState.fIndexBuffer = buffer; 2137 } 2138 2139 void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) { 2140 if (fHWGeometryState.fIndexBuffer == buffer) { 2141 // deleting bound buffer does implied bind to 0 2142 fHWGeometryState.fIndexBuffer = NULL; 2143 } 2144 } 2145 2146 void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { 2147 GrAssert(NULL != renderTarget); 2148 if (fHWBoundRenderTarget == renderTarget) { 2149 fHWBoundRenderTarget = NULL; 2150 } 2151 } 2152 2153 void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { 2154 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 2155 if (fHWBoundTextures[s] == texture) { 2156 // deleting bound texture does implied bind to 0 2157 fHWBoundTextures[s] = NULL; 2158 } 2159 } 2160 } 2161 2162 bool GrGpuGL::configToGLFormats(GrPixelConfig config, 2163 bool getSizedInternalFormat, 2164 GrGLenum* internalFormat, 2165 GrGLenum* externalFormat, 2166 GrGLenum* externalType) { 2167 GrGLenum dontCare; 2168 if (NULL == internalFormat) { 2169 internalFormat = &dontCare; 2170 } 2171 if (NULL == externalFormat) { 2172 externalFormat = &dontCare; 2173 } 2174 if (NULL == externalType) { 2175 externalType = &dontCare; 2176 } 2177 2178 switch (config) { 2179 case kRGBA_8888_GrPixelConfig: 2180 *internalFormat = GR_GL_RGBA; 2181 *externalFormat = GR_GL_RGBA; 2182 if (getSizedInternalFormat) { 2183 *internalFormat = GR_GL_RGBA8; 2184 } else { 2185 *internalFormat = GR_GL_RGBA; 2186 } 2187 *externalType = GR_GL_UNSIGNED_BYTE; 2188 break; 2189 case kBGRA_8888_GrPixelConfig: 2190 if (!this->glCaps().bgraFormatSupport()) { 2191 return false; 2192 } 2193 if (this->glCaps().bgraIsInternalFormat()) { 2194 if (getSizedInternalFormat) { 2195 *internalFormat = GR_GL_BGRA8; 2196 } else { 2197 *internalFormat = GR_GL_BGRA; 2198 } 2199 } else { 2200 if (getSizedInternalFormat) { 2201 *internalFormat = GR_GL_RGBA8; 2202 } else { 2203 *internalFormat = GR_GL_RGBA; 2204 } 2205 } 2206 *externalFormat = GR_GL_BGRA; 2207 *externalType = GR_GL_UNSIGNED_BYTE; 2208 break; 2209 case kRGB_565_GrPixelConfig: 2210 *internalFormat = GR_GL_RGB; 2211 *externalFormat = GR_GL_RGB; 2212 if (getSizedInternalFormat) { 2213 if (this->glBinding() == kDesktop_GrGLBinding) { 2214 return false; 2215 } else { 2216 *internalFormat = GR_GL_RGB565; 2217 } 2218 } else { 2219 *internalFormat = GR_GL_RGB; 2220 } 2221 *externalType = GR_GL_UNSIGNED_SHORT_5_6_5; 2222 break; 2223 case kRGBA_4444_GrPixelConfig: 2224 *internalFormat = GR_GL_RGBA; 2225 *externalFormat = GR_GL_RGBA; 2226 if (getSizedInternalFormat) { 2227 *internalFormat = GR_GL_RGBA4; 2228 } else { 2229 *internalFormat = GR_GL_RGBA; 2230 } 2231 *externalType = GR_GL_UNSIGNED_SHORT_4_4_4_4; 2232 break; 2233 case kIndex_8_GrPixelConfig: 2234 if (this->getCaps().eightBitPaletteSupport()) { 2235 *internalFormat = GR_GL_PALETTE8_RGBA8; 2236 // glCompressedTexImage doesn't take external params 2237 *externalFormat = GR_GL_PALETTE8_RGBA8; 2238 // no sized/unsized internal format distinction here 2239 *internalFormat = GR_GL_PALETTE8_RGBA8; 2240 // unused with CompressedTexImage 2241 *externalType = GR_GL_UNSIGNED_BYTE; 2242 } else { 2243 return false; 2244 } 2245 break; 2246 case kAlpha_8_GrPixelConfig: 2247 if (this->glCaps().textureRedSupport()) { 2248 *internalFormat = GR_GL_RED; 2249 *externalFormat = GR_GL_RED; 2250 if (getSizedInternalFormat) { 2251 *internalFormat = GR_GL_R8; 2252 } else { 2253 *internalFormat = GR_GL_RED; 2254 } 2255 *externalType = GR_GL_UNSIGNED_BYTE; 2256 } else { 2257 *internalFormat = GR_GL_ALPHA; 2258 *externalFormat = GR_GL_ALPHA; 2259 if (getSizedInternalFormat) { 2260 *internalFormat = GR_GL_ALPHA8; 2261 } else { 2262 *internalFormat = GR_GL_ALPHA; 2263 } 2264 *externalType = GR_GL_UNSIGNED_BYTE; 2265 } 2266 break; 2267 default: 2268 return false; 2269 } 2270 return true; 2271 } 2272 2273 void GrGpuGL::setTextureUnit(int unit) { 2274 GrAssert(unit >= 0 && unit < GrDrawState::kNumStages); 2275 if (fHWActiveTextureUnitIdx != unit) { 2276 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit)); 2277 fHWActiveTextureUnitIdx = unit; 2278 } 2279 } 2280 2281 void GrGpuGL::setSpareTextureUnit() { 2282 if (fHWActiveTextureUnitIdx != (GR_GL_TEXTURE0 + SPARE_TEX_UNIT)) { 2283 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); 2284 fHWActiveTextureUnitIdx = SPARE_TEX_UNIT; 2285 } 2286 } 2287 2288 void GrGpuGL::setBuffers(bool indexed, 2289 int* extraVertexOffset, 2290 int* extraIndexOffset) { 2291 2292 GrAssert(NULL != extraVertexOffset); 2293 2294 const GeometryPoolState& geoPoolState = this->getGeomPoolState(); 2295 2296 GrGLVertexBuffer* vbuf; 2297 switch (this->getGeomSrc().fVertexSrc) { 2298 case kBuffer_GeometrySrcType: 2299 *extraVertexOffset = 0; 2300 vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer; 2301 break; 2302 case kArray_GeometrySrcType: 2303 case kReserved_GeometrySrcType: 2304 this->finalizeReservedVertices(); 2305 *extraVertexOffset = geoPoolState.fPoolStartVertex; 2306 vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer; 2307 break; 2308 default: 2309 vbuf = NULL; // suppress warning 2310 GrCrash("Unknown geometry src type!"); 2311 } 2312 2313 GrAssert(NULL != vbuf); 2314 GrAssert(!vbuf->isLocked()); 2315 if (fHWGeometryState.fVertexBuffer != vbuf) { 2316 GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, vbuf->bufferID())); 2317 fHWGeometryState.fArrayPtrsDirty = true; 2318 fHWGeometryState.fVertexBuffer = vbuf; 2319 } 2320 2321 if (indexed) { 2322 GrAssert(NULL != extraIndexOffset); 2323 2324 GrGLIndexBuffer* ibuf; 2325 switch (this->getGeomSrc().fIndexSrc) { 2326 case kBuffer_GeometrySrcType: 2327 *extraIndexOffset = 0; 2328 ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer; 2329 break; 2330 case kArray_GeometrySrcType: 2331 case kReserved_GeometrySrcType: 2332 this->finalizeReservedIndices(); 2333 *extraIndexOffset = geoPoolState.fPoolStartIndex; 2334 ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer; 2335 break; 2336 default: 2337 ibuf = NULL; // suppress warning 2338 GrCrash("Unknown geometry src type!"); 2339 } 2340 2341 GrAssert(NULL != ibuf); 2342 GrAssert(!ibuf->isLocked()); 2343 if (fHWGeometryState.fIndexBuffer != ibuf) { 2344 GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibuf->bufferID())); 2345 fHWGeometryState.fIndexBuffer = ibuf; 2346 } 2347 } 2348 } 2349