1 /* 2 Copyright 2011 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #include "GrGpuGL.h" 18 #include "GrMemory.h" 19 #include "GrTypes.h" 20 21 static const GrGLuint GR_MAX_GLUINT = ~0; 22 static const GrGLint GR_INVAL_GLINT = ~0; 23 24 // we use a spare texture unit to avoid 25 // mucking with the state of any of the stages. 26 static const int SPARE_TEX_UNIT = GrGpuGL::kNumStages; 27 28 #define SKIP_CACHE_CHECK true 29 30 static const GrGLenum gXfermodeCoeff2Blend[] = { 31 GR_GL_ZERO, 32 GR_GL_ONE, 33 GR_GL_SRC_COLOR, 34 GR_GL_ONE_MINUS_SRC_COLOR, 35 GR_GL_DST_COLOR, 36 GR_GL_ONE_MINUS_DST_COLOR, 37 GR_GL_SRC_ALPHA, 38 GR_GL_ONE_MINUS_SRC_ALPHA, 39 GR_GL_DST_ALPHA, 40 GR_GL_ONE_MINUS_DST_ALPHA, 41 GR_GL_CONSTANT_COLOR, 42 GR_GL_ONE_MINUS_CONSTANT_COLOR, 43 GR_GL_CONSTANT_ALPHA, 44 GR_GL_ONE_MINUS_CONSTANT_ALPHA, 45 46 // extended blend coeffs 47 GR_GL_SRC1_COLOR, 48 GR_GL_ONE_MINUS_SRC1_COLOR, 49 GR_GL_SRC1_ALPHA, 50 GR_GL_ONE_MINUS_SRC1_ALPHA, 51 }; 52 53 bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { 54 static const bool gCoeffReferencesBlendConst[] = { 55 false, 56 false, 57 false, 58 false, 59 false, 60 false, 61 false, 62 false, 63 false, 64 false, 65 true, 66 true, 67 true, 68 true, 69 70 // extended blend coeffs 71 false, 72 false, 73 false, 74 false, 75 }; 76 return gCoeffReferencesBlendConst[coeff]; 77 GR_STATIC_ASSERT(kTotalBlendCoeffCount == GR_ARRAY_COUNT(gCoeffReferencesBlendConst)); 78 79 GR_STATIC_ASSERT(0 == kZero_BlendCoeff); 80 GR_STATIC_ASSERT(1 == kOne_BlendCoeff); 81 GR_STATIC_ASSERT(2 == kSC_BlendCoeff); 82 GR_STATIC_ASSERT(3 == kISC_BlendCoeff); 83 GR_STATIC_ASSERT(4 == kDC_BlendCoeff); 84 GR_STATIC_ASSERT(5 == kIDC_BlendCoeff); 85 GR_STATIC_ASSERT(6 == kSA_BlendCoeff); 86 GR_STATIC_ASSERT(7 == kISA_BlendCoeff); 87 GR_STATIC_ASSERT(8 == kDA_BlendCoeff); 88 GR_STATIC_ASSERT(9 == kIDA_BlendCoeff); 89 GR_STATIC_ASSERT(10 == kConstC_BlendCoeff); 90 GR_STATIC_ASSERT(11 == kIConstC_BlendCoeff); 91 GR_STATIC_ASSERT(12 == kConstA_BlendCoeff); 92 GR_STATIC_ASSERT(13 == kIConstA_BlendCoeff); 93 94 GR_STATIC_ASSERT(14 == kS2C_BlendCoeff); 95 GR_STATIC_ASSERT(15 == kIS2C_BlendCoeff); 96 GR_STATIC_ASSERT(16 == kS2A_BlendCoeff); 97 GR_STATIC_ASSERT(17 == kIS2A_BlendCoeff); 98 99 // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope 100 GR_STATIC_ASSERT(kTotalBlendCoeffCount == GR_ARRAY_COUNT(gXfermodeCoeff2Blend)); 101 } 102 103 /////////////////////////////////////////////////////////////////////////////// 104 105 void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture, 106 GrSamplerState::SampleMode mode, 107 GrMatrix* matrix) { 108 GrAssert(NULL != texture); 109 GrAssert(NULL != matrix); 110 if (GR_Scalar1 != texture->contentScaleX() || 111 GR_Scalar1 != texture->contentScaleY()) { 112 if (GrSamplerState::kRadial_SampleMode == mode) { 113 GrMatrix scale; 114 scale.setScale(texture->contentScaleX(), texture->contentScaleX()); 115 matrix->postConcat(scale); 116 } else if (GrSamplerState::kNormal_SampleMode == mode) { 117 GrMatrix scale; 118 scale.setScale(texture->contentScaleX(), texture->contentScaleY()); 119 matrix->postConcat(scale); 120 } else { 121 GrPrintf("We haven't handled NPOT adjustment for other sample modes!"); 122 } 123 } 124 GrGLTexture::Orientation orientation = texture->orientation(); 125 if (GrGLTexture::kBottomUp_Orientation == orientation) { 126 GrMatrix invY; 127 invY.setAll(GR_Scalar1, 0, 0, 128 0, -GR_Scalar1, GR_Scalar1, 129 0, 0, GrMatrix::I()[8]); 130 matrix->postConcat(invY); 131 } else { 132 GrAssert(GrGLTexture::kTopDown_Orientation == orientation); 133 } 134 } 135 136 bool GrGpuGL::TextureMatrixIsIdentity(const GrGLTexture* texture, 137 const GrSamplerState& sampler) { 138 GrAssert(NULL != texture); 139 if (!sampler.getMatrix().isIdentity()) { 140 return false; 141 } 142 if (GR_Scalar1 != texture->contentScaleX() || 143 GR_Scalar1 != texture->contentScaleY()) { 144 return false; 145 } 146 GrGLTexture::Orientation orientation = texture->orientation(); 147 if (GrGLTexture::kBottomUp_Orientation == orientation) { 148 return false; 149 } else { 150 GrAssert(GrGLTexture::kTopDown_Orientation == orientation); 151 } 152 return true; 153 } 154 155 /////////////////////////////////////////////////////////////////////////////// 156 157 static bool gPrintStartupSpew; 158 159 static bool fbo_test(int w, int h) { 160 161 GrGLint savedFBO; 162 GrGLint savedTexUnit; 163 GR_GL_GetIntegerv(GR_GL_ACTIVE_TEXTURE, &savedTexUnit); 164 GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &savedFBO); 165 166 GR_GL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); 167 168 GrGLuint testFBO; 169 GR_GL(GenFramebuffers(1, &testFBO)); 170 GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, testFBO)); 171 GrGLuint testRTTex; 172 GR_GL(GenTextures(1, &testRTTex)); 173 GR_GL(BindTexture(GR_GL_TEXTURE_2D, testRTTex)); 174 // some implementations require texture to be mip-map complete before 175 // FBO with level 0 bound as color attachment will be framebuffer complete. 176 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST)); 177 GR_GL(TexImage2D(GR_GL_TEXTURE_2D, 0, GR_GL_RGBA, w, h, 178 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, NULL)); 179 GR_GL(BindTexture(GR_GL_TEXTURE_2D, 0)); 180 GR_GL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, 181 GR_GL_TEXTURE_2D, testRTTex, 0)); 182 GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 183 GR_GL(DeleteFramebuffers(1, &testFBO)); 184 GR_GL(DeleteTextures(1, &testRTTex)); 185 186 GR_GL(ActiveTexture(savedTexUnit)); 187 GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, savedFBO)); 188 189 return status == GR_GL_FRAMEBUFFER_COMPLETE; 190 } 191 192 GrGpuGL::GrGpuGL() { 193 194 if (gPrintStartupSpew) { 195 GrPrintf("------------------------- create GrGpuGL %p --------------\n", 196 this); 197 GrPrintf("------ VENDOR %s\n", 198 GrGLGetGLInterface()->fGetString(GR_GL_VENDOR)); 199 GrPrintf("------ RENDERER %s\n", 200 GrGLGetGLInterface()->fGetString(GR_GL_RENDERER)); 201 GrPrintf("------ VERSION %s\n", 202 GrGLGetGLInterface()->fGetString(GR_GL_VERSION)); 203 GrPrintf("------ EXTENSIONS\n %s \n", 204 GrGLGetGLInterface()->fGetString(GR_GL_EXTENSIONS)); 205 } 206 207 GrGLClearErr(); 208 209 resetDirtyFlags(); 210 211 GrGLint maxTextureUnits; 212 // check FS and fixed-function texture unit limits 213 // we only use textures in the fragment stage currently. 214 // checks are > to make sure we have a spare unit. 215 if (GR_GL_SUPPORT_DESKTOP || GR_GL_SUPPORT_ES2) { 216 GR_GL_GetIntegerv(GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); 217 GrAssert(maxTextureUnits > kNumStages); 218 } 219 if (GR_GL_SUPPORT_DESKTOP || GR_GL_SUPPORT_ES1) { 220 GR_GL_GetIntegerv(GR_GL_MAX_TEXTURE_UNITS, &maxTextureUnits); 221 GrAssert(maxTextureUnits > kNumStages); 222 } 223 if (GR_GL_SUPPORT_ES2) { 224 GR_GL_GetIntegerv(GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS, 225 &fMaxFragmentUniformVectors); 226 } else if (GR_GL_SUPPORT_DESKTOP) { 227 GrGLint max; 228 GR_GL_GetIntegerv(GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max); 229 fMaxFragmentUniformVectors = max / 4; 230 } else { 231 fMaxFragmentUniformVectors = 16; 232 } 233 234 //////////////////////////////////////////////////////////////////////////// 235 // Check for supported features. 236 237 int major, minor; 238 gl_version(&major, &minor); 239 240 GrGLint numFormats; 241 GR_GL_GetIntegerv(GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats); 242 GrAutoSTMalloc<10, GrGLint> formats(numFormats); 243 GR_GL_GetIntegerv(GR_GL_COMPRESSED_TEXTURE_FORMATS, formats); 244 for (int i = 0; i < numFormats; ++i) { 245 if (formats[i] == GR_GL_PALETTE8_RGBA8) { 246 f8bitPaletteSupport = true; 247 break; 248 } 249 } 250 251 if (gPrintStartupSpew) { 252 GrPrintf("Palette8 support: %s\n", (f8bitPaletteSupport ? "YES" : "NO")); 253 } 254 255 GR_STATIC_ASSERT(0 == kNone_GrAALevel); 256 GR_STATIC_ASSERT(1 == kLow_GrAALevel); 257 GR_STATIC_ASSERT(2 == kMed_GrAALevel); 258 GR_STATIC_ASSERT(3 == kHigh_GrAALevel); 259 260 memset(fAASamples, 0, sizeof(fAASamples)); 261 fMSFBOType = kNone_MSFBO; 262 if (GR_GL_SUPPORT_ES) { 263 if (has_gl_extension("GL_CHROMIUM_framebuffer_multisample")) { 264 // chrome's extension is equivalent to the EXT msaa 265 // and fbo_blit extensions. 266 fMSFBOType = kDesktopEXT_MSFBO; 267 } else if (has_gl_extension("GL_APPLE_framebuffer_multisample")) { 268 fMSFBOType = kAppleES_MSFBO; 269 } 270 } else { 271 GrAssert(GR_GL_SUPPORT_DESKTOP); 272 if ((major >= 3) || has_gl_extension("GL_ARB_framebuffer_object")) { 273 fMSFBOType = kDesktopARB_MSFBO; 274 } else if (has_gl_extension("GL_EXT_framebuffer_multisample") && 275 has_gl_extension("GL_EXT_framebuffer_blit")) { 276 fMSFBOType = kDesktopEXT_MSFBO; 277 } 278 } 279 if (gPrintStartupSpew) { 280 switch (fMSFBOType) { 281 case kNone_MSFBO: 282 GrPrintf("MSAA Support: NONE\n"); 283 break; 284 case kDesktopARB_MSFBO: 285 GrPrintf("MSAA Support: DESKTOP ARB.\n"); 286 break; 287 case kDesktopEXT_MSFBO: 288 GrPrintf("MSAA Support: DESKTOP EXT.\n"); 289 break; 290 case kAppleES_MSFBO: 291 GrPrintf("MSAA Support: APPLE ES.\n"); 292 break; 293 } 294 } 295 296 if (kNone_MSFBO != fMSFBOType) { 297 GrGLint maxSamples; 298 GR_GL_GetIntegerv(GR_GL_MAX_SAMPLES, &maxSamples); 299 if (maxSamples > 1 ) { 300 fAASamples[kNone_GrAALevel] = 0; 301 fAASamples[kLow_GrAALevel] = GrMax(2, 302 GrFixedFloorToInt((GR_FixedHalf) * 303 maxSamples)); 304 fAASamples[kMed_GrAALevel] = GrMax(2, 305 GrFixedFloorToInt(((GR_Fixed1*3)/4) * 306 maxSamples)); 307 fAASamples[kHigh_GrAALevel] = maxSamples; 308 } 309 if (gPrintStartupSpew) { 310 GrPrintf("\tMax Samples: %d\n", maxSamples); 311 } 312 } 313 fFSAASupport = fAASamples[kHigh_GrAALevel] > 0; 314 315 if (GR_GL_SUPPORT_DESKTOP) { 316 fHasStencilWrap = (major >= 2 || (major == 1 && minor >= 4)) || 317 has_gl_extension("GL_EXT_stencil_wrap"); 318 } else { 319 fHasStencilWrap = (major >= 2) || has_gl_extension("GL_OES_stencil_wrap"); 320 } 321 if (gPrintStartupSpew) { 322 GrPrintf("Stencil Wrap: %s\n", (fHasStencilWrap ? "YES" : "NO")); 323 } 324 325 if (GR_GL_SUPPORT_DESKTOP) { 326 // we could also look for GL_ATI_separate_stencil extension or 327 // GL_EXT_stencil_two_side but they use different function signatures 328 // than GL2.0+ (and than each other). 329 fTwoSidedStencilSupport = (major >= 2); 330 // supported on GL 1.4 and higher or by extension 331 fStencilWrapOpsSupport = (major > 1) || 332 ((1 == major) && (minor >= 4)) || 333 has_gl_extension("GL_EXT_stencil_wrap"); 334 } else { 335 // ES 2 has two sided stencil but 1.1 doesn't. There doesn't seem to be 336 // an ES1 extension. 337 fTwoSidedStencilSupport = (major >= 2); 338 // stencil wrap support is in ES2, ES1 requires extension. 339 fStencilWrapOpsSupport = (major > 1) || 340 has_gl_extension("GL_OES_stencil_wrap"); 341 } 342 if (gPrintStartupSpew) { 343 GrPrintf("Stencil Caps: TwoSide: %s, Wrap: %s\n", 344 (fTwoSidedStencilSupport ? "YES" : "NO"), 345 (fStencilWrapOpsSupport ? "YES" : "NO")); 346 } 347 348 if (GR_GL_SUPPORT_DESKTOP) { 349 fRGBA8Renderbuffer = true; 350 } else { 351 fRGBA8Renderbuffer = has_gl_extension("GL_OES_rgb8_rgba8"); 352 } 353 if (gPrintStartupSpew) { 354 GrPrintf("RGBA Renderbuffer: %s\n", (fRGBA8Renderbuffer ? "YES" : "NO")); 355 } 356 357 358 if (GR_GL_SUPPORT_ES) { 359 if (GR_GL_32BPP_COLOR_FORMAT == GR_GL_BGRA) { 360 GrAssert(has_gl_extension("GL_EXT_texture_format_BGRA8888")); 361 } 362 } 363 364 if (GR_GL_SUPPORT_DESKTOP) { 365 fBufferLockSupport = true; // we require VBO support and the desktop VBO 366 // extension includes glMapBuffer. 367 } else { 368 fBufferLockSupport = has_gl_extension("GL_OES_mapbuffer"); 369 } 370 371 if (gPrintStartupSpew) { 372 GrPrintf("Map Buffer: %s\n", (fBufferLockSupport ? "YES" : "NO")); 373 } 374 375 if (GR_GL_SUPPORT_DESKTOP) { 376 if (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) { 377 fNPOTTextureTileSupport = true; 378 fNPOTTextureSupport = true; 379 } else { 380 fNPOTTextureTileSupport = false; 381 fNPOTTextureSupport = false; 382 } 383 } else { 384 if (major >= 2) { 385 fNPOTTextureSupport = true; 386 fNPOTTextureTileSupport = has_gl_extension("GL_OES_texture_npot"); 387 } else { 388 fNPOTTextureSupport = 389 has_gl_extension("GL_APPLE_texture_2D_limited_npot"); 390 fNPOTTextureTileSupport = false; 391 } 392 } 393 394 fAALineSupport = GR_GL_SUPPORT_DESKTOP; 395 396 //////////////////////////////////////////////////////////////////////////// 397 // Experiments to determine limitations that can't be queried. TODO: Make 398 // these a preprocess that generate some compile time constants. 399 400 // sanity check to make sure we can at least create an FBO from a POT texture 401 402 bool simpleFBOSuccess = fbo_test(128, 128); 403 if (gPrintStartupSpew) { 404 if (!simpleFBOSuccess) { 405 GrPrintf("FBO Sanity Test: FAILED\n"); 406 } else { 407 GrPrintf("FBO Sanity Test: PASSED\n"); 408 } 409 } 410 GrAssert(simpleFBOSuccess); 411 412 /* Experimentation has found that some GLs that support NPOT textures 413 do not support FBOs with a NPOT texture. They report "unsupported" FBO 414 status. I don't know how to explicitly query for this. Do an 415 experiment. Note they may support NPOT with a renderbuffer but not a 416 texture. Presumably, the implementation bloats the renderbuffer 417 internally to the next POT. 418 */ 419 bool fNPOTRenderTargetSupport = false; 420 if (fNPOTTextureSupport) { 421 fNPOTRenderTargetSupport = fbo_test(200, 200); 422 } 423 424 if (gPrintStartupSpew) { 425 if (fNPOTTextureSupport) { 426 GrPrintf("NPOT textures supported\n"); 427 if (fNPOTTextureTileSupport) { 428 GrPrintf("NPOT texture tiling supported\n"); 429 } else { 430 GrPrintf("NPOT texture tiling NOT supported\n"); 431 } 432 if (fNPOTRenderTargetSupport) { 433 GrPrintf("NPOT render targets supported\n"); 434 } else { 435 GrPrintf("NPOT render targets NOT supported\n"); 436 } 437 } else { 438 GrPrintf("NPOT textures NOT supported\n"); 439 } 440 } 441 442 GR_GL_GetIntegerv(GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureDimension); 443 444 /* The iPhone 4 has a restriction that for an FBO with texture color 445 attachment with height <= 8 then the width must be <= height. Here 446 we look for such a limitation. 447 */ 448 fMinRenderTargetHeight = GR_INVAL_GLINT; 449 GrGLint maxRenderSize; 450 GR_GL_GetIntegerv(GR_GL_MAX_RENDERBUFFER_SIZE, &maxRenderSize); 451 // fbo_test creates FBOs with texture bound to the color attachment 452 maxRenderSize = GrMin(maxRenderSize, fMaxTextureDimension); 453 454 if (gPrintStartupSpew) { 455 GrPrintf("Small height FBO texture experiments\n"); 456 } 457 458 for (GrGLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? ++i : i *= 2) { 459 GrGLuint w = maxRenderSize; 460 GrGLuint h = i; 461 if (fbo_test(w, h)) { 462 if (gPrintStartupSpew) { 463 GrPrintf("\t[%d, %d]: PASSED\n", w, h); 464 } 465 fMinRenderTargetHeight = i; 466 break; 467 } else { 468 if (gPrintStartupSpew) { 469 GrPrintf("\t[%d, %d]: FAILED\n", w, h); 470 } 471 } 472 } 473 GrAssert(GR_INVAL_GLINT != fMinRenderTargetHeight); 474 475 if (gPrintStartupSpew) { 476 GrPrintf("Small width FBO texture experiments\n"); 477 } 478 fMinRenderTargetWidth = GR_MAX_GLUINT; 479 for (GrGLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? i *= 2 : ++i) { 480 GrGLuint w = i; 481 GrGLuint h = maxRenderSize; 482 if (fbo_test(w, h)) { 483 if (gPrintStartupSpew) { 484 GrPrintf("\t[%d, %d]: PASSED\n", w, h); 485 } 486 fMinRenderTargetWidth = i; 487 break; 488 } else { 489 if (gPrintStartupSpew) { 490 GrPrintf("\t[%d, %d]: FAILED\n", w, h); 491 } 492 } 493 } 494 GrAssert(GR_INVAL_GLINT != fMinRenderTargetWidth); 495 } 496 497 GrGpuGL::~GrGpuGL() { 498 } 499 500 void GrGpuGL::resetContext() { 501 // We detect cases when blending is effectively off 502 fHWBlendDisabled = false; 503 GR_GL(Enable(GR_GL_BLEND)); 504 505 // we don't use the zb at all 506 GR_GL(Disable(GR_GL_DEPTH_TEST)); 507 GR_GL(DepthMask(GR_GL_FALSE)); 508 509 GR_GL(Disable(GR_GL_CULL_FACE)); 510 GR_GL(FrontFace(GR_GL_CCW)); 511 fHWDrawState.fDrawFace = kBoth_DrawFace; 512 513 GR_GL(Disable(GR_GL_DITHER)); 514 if (GR_GL_SUPPORT_DESKTOP) { 515 GR_GL(Disable(GR_GL_LINE_SMOOTH)); 516 GR_GL(Disable(GR_GL_POINT_SMOOTH)); 517 GR_GL(Disable(GR_GL_MULTISAMPLE)); 518 fHWAAState.fMSAAEnabled = false; 519 fHWAAState.fSmoothLineEnabled = false; 520 } 521 522 GR_GL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 523 fHWDrawState.fFlagBits = 0; 524 525 // we only ever use lines in hairline mode 526 GR_GL(LineWidth(1)); 527 528 // invalid 529 fActiveTextureUnitIdx = -1; 530 531 // illegal values 532 fHWDrawState.fSrcBlend = (GrBlendCoeff)-1; 533 fHWDrawState.fDstBlend = (GrBlendCoeff)-1; 534 535 fHWDrawState.fBlendConstant = 0x00000000; 536 GR_GL(BlendColor(0,0,0,0)); 537 538 fHWDrawState.fColor = GrColor_ILLEGAL; 539 540 fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); 541 542 for (int s = 0; s < kNumStages; ++s) { 543 fHWDrawState.fTextures[s] = NULL; 544 fHWDrawState.fSamplerStates[s].setRadial2Params(-GR_ScalarMax, 545 -GR_ScalarMax, 546 true); 547 548 fHWDrawState.fSamplerStates[s].setMatrix(GrMatrix::InvalidMatrix()); 549 } 550 551 fHWBounds.fScissorRect.invalidate(); 552 fHWBounds.fScissorEnabled = false; 553 GR_GL(Disable(GR_GL_SCISSOR_TEST)); 554 fHWBounds.fViewportRect.invalidate(); 555 556 fHWDrawState.fStencilSettings.invalidate(); 557 fHWStencilClip = false; 558 fClipState.fClipIsDirty = true; 559 560 fHWGeometryState.fIndexBuffer = NULL; 561 fHWGeometryState.fVertexBuffer = NULL; 562 563 fHWGeometryState.fArrayPtrsDirty = true; 564 565 GR_GL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 566 fHWDrawState.fRenderTarget = NULL; 567 } 568 569 GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) { 570 571 bool isTexture = kTexture_GrPlatformSurfaceType == desc.fSurfaceType || 572 kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType; 573 bool isRenderTarget = kRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType || 574 kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType; 575 576 GrGLRenderTarget::GLRenderTargetIDs rtIDs; 577 if (isRenderTarget) { 578 rtIDs.fRTFBOID = desc.fPlatformRenderTarget; 579 if (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) { 580 if (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) { 581 rtIDs.fTexFBOID = desc.fPlatformResolveDestination; 582 } else { 583 GrAssert(!isTexture); // this should have been filtered by GrContext 584 rtIDs.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 585 } 586 } else { 587 rtIDs.fTexFBOID = desc.fPlatformRenderTarget; 588 } 589 // we don't know what the RB ids are without glGets and we don't care 590 // since we aren't responsible for deleting them. 591 rtIDs.fStencilRenderbufferID = 0; 592 rtIDs.fMSColorRenderbufferID = 0; 593 594 rtIDs.fOwnIDs = false; 595 } else { 596 rtIDs.reset(); 597 } 598 599 if (isTexture) { 600 GrGLTexture::GLTextureDesc texDesc; 601 GrGLenum dontCare; 602 if (!canBeTexture(desc.fConfig, &dontCare, 603 &texDesc.fUploadFormat, 604 &texDesc.fUploadType)) { 605 return NULL; 606 } 607 608 GrGLTexture::TexParams params; 609 610 texDesc.fAllocWidth = texDesc.fContentWidth = desc.fWidth; 611 texDesc.fAllocHeight = texDesc.fContentHeight = desc.fHeight; 612 613 texDesc.fFormat = texDesc.fFormat; 614 texDesc.fOrientation = GrGLTexture::kBottomUp_Orientation; 615 texDesc.fStencilBits = desc.fStencilBits; 616 texDesc.fTextureID = desc.fPlatformTexture; 617 texDesc.fUploadByteCount = GrBytesPerPixel(desc.fConfig); 618 texDesc.fOwnsID = false; 619 620 params.invalidate(); // rather than do glGets. 621 622 return new GrGLTexture(this, texDesc, rtIDs, params); 623 } else { 624 GrGLIRect viewport; 625 viewport.fLeft = 0; 626 viewport.fBottom = 0; 627 viewport.fWidth = desc.fWidth; 628 viewport.fHeight = desc.fHeight; 629 630 return new GrGLRenderTarget(this, rtIDs, NULL, desc.fStencilBits, 631 kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags, 632 viewport, NULL); 633 } 634 } 635 636 GrRenderTarget* GrGpuGL::onCreateRenderTargetFrom3DApiState() { 637 638 GrGLRenderTarget::GLRenderTargetIDs rtIDs; 639 640 GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, (GrGLint*)&rtIDs.fRTFBOID); 641 rtIDs.fTexFBOID = rtIDs.fRTFBOID; 642 rtIDs.fMSColorRenderbufferID = 0; 643 rtIDs.fStencilRenderbufferID = 0; 644 645 GrGLIRect viewport; 646 viewport.setFromGLViewport(); 647 GrGLuint stencilBits; 648 GR_GL_GetIntegerv(GR_GL_STENCIL_BITS, (GrGLint*)&stencilBits); 649 650 GrGLint samples; 651 GR_GL_GetIntegerv(GR_GL_SAMPLES, &samples); 652 653 rtIDs.fOwnIDs = false; 654 655 return new GrGLRenderTarget(this, rtIDs, NULL, stencilBits, 656 (samples > 0), viewport, NULL); 657 } 658 659 /////////////////////////////////////////////////////////////////////////////// 660 661 static const GrGLuint UNKNOWN_BITS = ~0; 662 663 struct StencilFormat { 664 GrGLenum fEnum; 665 GrGLuint fBits; 666 bool fPacked; 667 }; 668 669 const StencilFormat* GrGLStencilFormats() { 670 // defines stencil formats from more to less preferred 671 static const StencilFormat desktopStencilFormats[] = { 672 {GR_GL_STENCIL_INDEX8, 8, false}, 673 {GR_GL_STENCIL_INDEX16, 16, false}, 674 {GR_GL_DEPTH24_STENCIL8, 8, true }, 675 {GR_GL_STENCIL_INDEX4, 4, false}, 676 {GR_GL_STENCIL_INDEX, UNKNOWN_BITS, false}, 677 {GR_GL_DEPTH_STENCIL, UNKNOWN_BITS, true }, 678 {0, 0, false} 679 }; 680 681 static const StencilFormat esStencilFormats[] = { 682 {GR_GL_STENCIL_INDEX8, 8, false}, 683 {GR_GL_DEPTH24_STENCIL8, 8, true }, 684 {GR_GL_STENCIL_INDEX4, 4, false}, 685 {0, 0, false} 686 }; 687 688 if (GR_GL_SUPPORT_DESKTOP) { 689 return desktopStencilFormats; 690 } else { 691 return esStencilFormats; 692 } 693 } 694 695 // good to set a break-point here to know when createTexture fails 696 static GrTexture* return_null_texture() { 697 // GrAssert(!"null texture"); 698 return NULL; 699 } 700 701 #if GR_DEBUG 702 static size_t as_size_t(int x) { 703 return x; 704 } 705 #endif 706 707 GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc, 708 const void* srcData, 709 size_t rowBytes) { 710 711 #if GR_COLLECT_STATS 712 ++fStats.fTextureCreateCnt; 713 #endif 714 715 this->setSpareTextureUnit(); 716 717 static const GrGLTexture::TexParams DEFAULT_PARAMS = { 718 GR_GL_NEAREST, 719 GR_GL_CLAMP_TO_EDGE, 720 GR_GL_CLAMP_TO_EDGE 721 }; 722 723 GrGLTexture::GLTextureDesc glDesc; 724 GrGLenum internalFormat; 725 726 glDesc.fContentWidth = desc.fWidth; 727 glDesc.fContentHeight = desc.fHeight; 728 glDesc.fAllocWidth = desc.fWidth; 729 glDesc.fAllocHeight = desc.fHeight; 730 glDesc.fStencilBits = 0; 731 glDesc.fFormat = desc.fFormat; 732 glDesc.fOwnsID = true; 733 734 bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit); 735 if (!canBeTexture(desc.fFormat, 736 &internalFormat, 737 &glDesc.fUploadFormat, 738 &glDesc.fUploadType)) { 739 return return_null_texture(); 740 } 741 742 GrAssert(as_size_t(desc.fAALevel) < GR_ARRAY_COUNT(fAASamples)); 743 GrGLint samples = fAASamples[desc.fAALevel]; 744 if (kNone_MSFBO == fMSFBOType && desc.fAALevel != kNone_GrAALevel) { 745 GrPrintf("AA RT requested but not supported on this platform."); 746 } 747 748 GR_GL(GenTextures(1, &glDesc.fTextureID)); 749 if (!glDesc.fTextureID) { 750 return return_null_texture(); 751 } 752 753 glDesc.fUploadByteCount = GrBytesPerPixel(desc.fFormat); 754 755 // in case we need a temporary, trimmed copy of the src pixels 756 GrAutoSMalloc<128 * 128> trimStorage; 757 758 /* 759 * check if our srcData has extra bytes past each row. If so, we need 760 * to trim those off here, since GL doesn't let us pass the rowBytes as 761 * a parameter to glTexImage2D 762 */ 763 if (GR_GL_SUPPORT_DESKTOP) { 764 if (srcData) { 765 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 766 rowBytes / glDesc.fUploadByteCount)); 767 } 768 } else { 769 size_t trimRowBytes = desc.fWidth * glDesc.fUploadByteCount; 770 if (srcData && (trimRowBytes < rowBytes)) { 771 // copy the data into our new storage, skipping the trailing bytes 772 size_t trimSize = desc.fHeight * trimRowBytes; 773 const char* src = (const char*)srcData; 774 char* dst = (char*)trimStorage.realloc(trimSize); 775 for (uint32_t y = 0; y < desc.fHeight; y++) { 776 memcpy(dst, src, trimRowBytes); 777 src += rowBytes; 778 dst += trimRowBytes; 779 } 780 // now point srcData to our trimmed version 781 srcData = trimStorage.get(); 782 } 783 } 784 785 if (renderTarget) { 786 if (!this->npotRenderTargetSupport()) { 787 glDesc.fAllocWidth = GrNextPow2(desc.fWidth); 788 glDesc.fAllocHeight = GrNextPow2(desc.fHeight); 789 } 790 791 glDesc.fAllocWidth = GrMax<int>(fMinRenderTargetWidth, 792 glDesc.fAllocWidth); 793 glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight, 794 glDesc.fAllocHeight); 795 } else if (!this->npotTextureSupport()) { 796 glDesc.fAllocWidth = GrNextPow2(desc.fWidth); 797 glDesc.fAllocHeight = GrNextPow2(desc.fHeight); 798 } 799 800 GR_GL(BindTexture(GR_GL_TEXTURE_2D, glDesc.fTextureID)); 801 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 802 GR_GL_TEXTURE_MAG_FILTER, 803 DEFAULT_PARAMS.fFilter)); 804 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 805 GR_GL_TEXTURE_MIN_FILTER, 806 DEFAULT_PARAMS.fFilter)); 807 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 808 GR_GL_TEXTURE_WRAP_S, 809 DEFAULT_PARAMS.fWrapS)); 810 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 811 GR_GL_TEXTURE_WRAP_T, 812 DEFAULT_PARAMS.fWrapT)); 813 814 GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, glDesc.fUploadByteCount)); 815 if (kIndex_8_GrPixelConfig == desc.fFormat && 816 supports8BitPalette()) { 817 // ES only supports CompressedTexImage2D, not CompressedTexSubimage2D 818 GrAssert(desc.fWidth == glDesc.fAllocWidth); 819 GrAssert(desc.fHeight == glDesc.fAllocHeight); 820 GrGLsizei imageSize = glDesc.fAllocWidth * glDesc.fAllocHeight + 821 kGrColorTableSize; 822 GR_GL(CompressedTexImage2D(GR_GL_TEXTURE_2D, 0, glDesc.fUploadFormat, 823 glDesc.fAllocWidth, glDesc.fAllocHeight, 824 0, imageSize, srcData)); 825 GrGLRestoreResetRowLength(); 826 } else { 827 if (NULL != srcData && (glDesc.fAllocWidth != desc.fWidth || 828 glDesc.fAllocHeight != desc.fHeight)) { 829 GR_GL(TexImage2D(GR_GL_TEXTURE_2D, 0, internalFormat, 830 glDesc.fAllocWidth, glDesc.fAllocHeight, 831 0, glDesc.fUploadFormat, glDesc.fUploadType, NULL)); 832 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, 0, 0, desc.fWidth, 833 desc.fHeight, glDesc.fUploadFormat, 834 glDesc.fUploadType, srcData)); 835 GrGLRestoreResetRowLength(); 836 837 uint32_t extraW = glDesc.fAllocWidth - desc.fWidth; 838 uint32_t extraH = glDesc.fAllocHeight - desc.fHeight; 839 uint32_t maxTexels = extraW * extraH; 840 maxTexels = GrMax(extraW * desc.fHeight, maxTexels); 841 maxTexels = GrMax(desc.fWidth * extraH, maxTexels); 842 843 GrAutoSMalloc<128*128> texels(glDesc.fUploadByteCount * maxTexels); 844 845 uint32_t rowSize = desc.fWidth * glDesc.fUploadByteCount; 846 if (extraH) { 847 uint8_t* lastRowStart = (uint8_t*) srcData + 848 (desc.fHeight - 1) * rowSize; 849 uint8_t* extraRowStart = (uint8_t*)texels.get(); 850 851 for (uint32_t i = 0; i < extraH; ++i) { 852 memcpy(extraRowStart, lastRowStart, rowSize); 853 extraRowStart += rowSize; 854 } 855 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, 0, desc.fHeight, desc.fWidth, 856 extraH, glDesc.fUploadFormat, glDesc.fUploadType, 857 texels.get())); 858 } 859 if (extraW) { 860 uint8_t* edgeTexel = (uint8_t*)srcData + rowSize - glDesc.fUploadByteCount; 861 uint8_t* extraTexel = (uint8_t*)texels.get(); 862 for (uint32_t j = 0; j < desc.fHeight; ++j) { 863 for (uint32_t i = 0; i < extraW; ++i) { 864 memcpy(extraTexel, edgeTexel, glDesc.fUploadByteCount); 865 extraTexel += glDesc.fUploadByteCount; 866 } 867 edgeTexel += rowSize; 868 } 869 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, desc.fWidth, 0, extraW, 870 desc.fHeight, glDesc.fUploadFormat, 871 glDesc.fUploadType, texels.get())); 872 } 873 if (extraW && extraH) { 874 uint8_t* cornerTexel = (uint8_t*)srcData + desc.fHeight * rowSize 875 - glDesc.fUploadByteCount; 876 uint8_t* extraTexel = (uint8_t*)texels.get(); 877 for (uint32_t i = 0; i < extraW*extraH; ++i) { 878 memcpy(extraTexel, cornerTexel, glDesc.fUploadByteCount); 879 extraTexel += glDesc.fUploadByteCount; 880 } 881 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, desc.fWidth, desc.fHeight, 882 extraW, extraH, glDesc.fUploadFormat, 883 glDesc.fUploadType, texels.get())); 884 } 885 886 } else { 887 GR_GL(TexImage2D(GR_GL_TEXTURE_2D, 0, internalFormat, glDesc.fAllocWidth, 888 glDesc.fAllocHeight, 0, glDesc.fUploadFormat, 889 glDesc.fUploadType, srcData)); 890 GrGLRestoreResetRowLength(); 891 } 892 } 893 894 glDesc.fOrientation = GrGLTexture::kTopDown_Orientation; 895 896 GrGLRenderTarget::GLRenderTargetIDs rtIDs; 897 rtIDs.fStencilRenderbufferID = 0; 898 rtIDs.fMSColorRenderbufferID = 0; 899 rtIDs.fRTFBOID = 0; 900 rtIDs.fTexFBOID = 0; 901 rtIDs.fOwnIDs = true; 902 GrGLenum msColorRenderbufferFormat = -1; 903 904 if (renderTarget) { 905 #if GR_COLLECT_STATS 906 ++fStats.fRenderTargetCreateCnt; 907 #endif 908 bool failed = true; 909 GrGLenum status; 910 GrGLint err; 911 912 // If need have both RT flag and srcData we have 913 // to invert the data before uploading because FBO 914 // will be rendered bottom up 915 GrAssert(NULL == srcData); 916 glDesc.fOrientation = GrGLTexture::kBottomUp_Orientation; 917 918 GR_GL(GenFramebuffers(1, &rtIDs.fTexFBOID)); 919 GrAssert(rtIDs.fTexFBOID); 920 921 // If we are using multisampling and we will create two FBOS We render 922 // to one and then resolve to the texture bound to the other. 923 if (samples > 1 && kNone_MSFBO != fMSFBOType) { 924 GR_GL(GenFramebuffers(1, &rtIDs.fRTFBOID)); 925 GrAssert(0 != rtIDs.fRTFBOID); 926 GR_GL(GenRenderbuffers(1, &rtIDs.fMSColorRenderbufferID)); 927 GrAssert(0 != rtIDs.fMSColorRenderbufferID); 928 if (!fboInternalFormat(desc.fFormat, &msColorRenderbufferFormat)) { 929 GR_GL(DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID)); 930 GR_GL(DeleteTextures(1, &glDesc.fTextureID)); 931 GR_GL(DeleteFramebuffers(1, &rtIDs.fTexFBOID)); 932 GR_GL(DeleteFramebuffers(1, &rtIDs.fRTFBOID)); 933 return return_null_texture(); 934 } 935 } else { 936 rtIDs.fRTFBOID = rtIDs.fTexFBOID; 937 } 938 if (!(kNoStencil_GrTextureFlagBit & desc.fFlags)) { 939 GR_GL(GenRenderbuffers(1, &rtIDs.fStencilRenderbufferID)); 940 GrAssert(0 != rtIDs.fStencilRenderbufferID); 941 } 942 943 // someone suggested that some systems might require 944 // unbinding the texture before we call FramebufferTexture2D 945 // (seems unlikely) 946 GR_GL(BindTexture(GR_GL_TEXTURE_2D, 0)); 947 948 err = ~GR_GL_NO_ERROR; 949 950 const StencilFormat* stencilFormats = GrGLStencilFormats(); 951 for (int i = 0; 0 != stencilFormats[i].fEnum; ++i) { 952 if (rtIDs.fStencilRenderbufferID) { 953 GR_GL(BindRenderbuffer(GR_GL_RENDERBUFFER, 954 rtIDs.fStencilRenderbufferID)); 955 if (samples > 1) { 956 GR_GL_NO_ERR(RenderbufferStorageMultisample( 957 GR_GL_RENDERBUFFER, 958 samples, 959 stencilFormats[i].fEnum, 960 glDesc.fAllocWidth, 961 glDesc.fAllocHeight)); 962 } else { 963 GR_GL_NO_ERR(RenderbufferStorage(GR_GL_RENDERBUFFER, 964 stencilFormats[i].fEnum, 965 glDesc.fAllocWidth, 966 glDesc.fAllocHeight)); 967 } 968 err = GrGLGetGLInterface()->fGetError(); 969 if (err != GR_GL_NO_ERROR) { 970 continue; 971 } 972 } 973 if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) { 974 GrAssert(samples > 1); 975 GR_GL(BindRenderbuffer(GR_GL_RENDERBUFFER, 976 rtIDs.fMSColorRenderbufferID)); 977 GR_GL_NO_ERR(RenderbufferStorageMultisample( 978 GR_GL_RENDERBUFFER, 979 samples, 980 msColorRenderbufferFormat, 981 glDesc.fAllocWidth, 982 glDesc.fAllocHeight)); 983 err = GrGLGetGLInterface()->fGetError(); 984 if (err != GR_GL_NO_ERROR) { 985 continue; 986 } 987 } 988 GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, rtIDs.fTexFBOID)); 989 990 #if GR_COLLECT_STATS 991 ++fStats.fRenderTargetChngCnt; 992 #endif 993 GR_GL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, 994 GR_GL_COLOR_ATTACHMENT0, 995 GR_GL_TEXTURE_2D, 996 glDesc.fTextureID, 0)); 997 if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) { 998 GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 999 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1000 GrPrintf("-- glCheckFramebufferStatus %x %d %d\n", 1001 status, desc.fWidth, desc.fHeight); 1002 continue; 1003 } 1004 GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, rtIDs.fRTFBOID)); 1005 #if GR_COLLECT_STATS 1006 ++fStats.fRenderTargetChngCnt; 1007 #endif 1008 GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1009 GR_GL_COLOR_ATTACHMENT0, 1010 GR_GL_RENDERBUFFER, 1011 rtIDs.fMSColorRenderbufferID)); 1012 1013 } 1014 if (rtIDs.fStencilRenderbufferID) { 1015 // bind the stencil to rt fbo if present, othewise the tex fbo 1016 GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1017 GR_GL_STENCIL_ATTACHMENT, 1018 GR_GL_RENDERBUFFER, 1019 rtIDs.fStencilRenderbufferID)); 1020 // if it is a packed format bind to depth also, otherwise 1021 // we may get an unsupported fbo completeness result 1022 if (stencilFormats[i].fPacked) { 1023 GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1024 GR_GL_DEPTH_ATTACHMENT, 1025 GR_GL_RENDERBUFFER, 1026 rtIDs.fStencilRenderbufferID)); 1027 } 1028 } 1029 status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1030 1031 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1032 GrPrintf("-- glCheckFramebufferStatus %x %d %d\n", 1033 status, desc.fWidth, desc.fHeight); 1034 // undo the depth bind 1035 if (rtIDs.fStencilRenderbufferID && 1036 stencilFormats[i].fPacked) { 1037 GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1038 GR_GL_DEPTH_ATTACHMENT, 1039 GR_GL_RENDERBUFFER, 1040 0)); 1041 } 1042 continue; 1043 } 1044 // we're successful! 1045 failed = false; 1046 if (rtIDs.fStencilRenderbufferID) { 1047 if (UNKNOWN_BITS == stencilFormats[i].fBits) { 1048 GR_GL_GetIntegerv(GR_GL_STENCIL_BITS, (GrGLint*)&glDesc.fStencilBits); 1049 } else { 1050 glDesc.fStencilBits = stencilFormats[i].fBits; 1051 } 1052 } 1053 break; 1054 } 1055 if (failed) { 1056 if (rtIDs.fStencilRenderbufferID) { 1057 GR_GL(DeleteRenderbuffers(1, &rtIDs.fStencilRenderbufferID)); 1058 } 1059 if (rtIDs.fMSColorRenderbufferID) { 1060 GR_GL(DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID)); 1061 } 1062 if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) { 1063 GR_GL(DeleteFramebuffers(1, &rtIDs.fRTFBOID)); 1064 } 1065 if (rtIDs.fTexFBOID) { 1066 GR_GL(DeleteFramebuffers(1, &rtIDs.fTexFBOID)); 1067 } 1068 GR_GL(DeleteTextures(1, &glDesc.fTextureID)); 1069 return return_null_texture(); 1070 } 1071 } 1072 #ifdef TRACE_TEXTURE_CREATION 1073 GrPrintf("--- new texture [%d] size=(%d %d) bpp=%d\n", 1074 tex->fTextureID, width, height, tex->fUploadByteCount); 1075 #endif 1076 GrGLTexture* tex = new GrGLTexture(this, glDesc, rtIDs, DEFAULT_PARAMS); 1077 1078 if (0 != rtIDs.fTexFBOID) { 1079 GrRenderTarget* rt = tex->asRenderTarget(); 1080 // We've messed with FBO state but may not have set the correct viewport 1081 // so just dirty the rendertarget state to force a resend. 1082 fHWDrawState.fRenderTarget = NULL; 1083 1084 // clear the new stencil buffer if we have one 1085 if (!(desc.fFlags & kNoStencil_GrTextureFlagBit)) { 1086 GrRenderTarget* rtSave = fCurrDrawState.fRenderTarget; 1087 fCurrDrawState.fRenderTarget = rt; 1088 this->clearStencil(0, ~0); 1089 fCurrDrawState.fRenderTarget = rtSave; 1090 } 1091 } 1092 return tex; 1093 } 1094 1095 GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) { 1096 GrGLuint id; 1097 GR_GL(GenBuffers(1, &id)); 1098 if (id) { 1099 GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, id)); 1100 fHWGeometryState.fArrayPtrsDirty = true; 1101 GrGLClearErr(); 1102 // make sure driver can allocate memory for this buffer 1103 GR_GL_NO_ERR(BufferData(GR_GL_ARRAY_BUFFER, size, NULL, 1104 dynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW)); 1105 if (GrGLGetGLInterface()->fGetError() != GR_GL_NO_ERROR) { 1106 GR_GL(DeleteBuffers(1, &id)); 1107 // deleting bound buffer does implicit bind to 0 1108 fHWGeometryState.fVertexBuffer = NULL; 1109 return NULL; 1110 } 1111 GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, id, 1112 size, dynamic); 1113 fHWGeometryState.fVertexBuffer = vertexBuffer; 1114 return vertexBuffer; 1115 } 1116 return NULL; 1117 } 1118 1119 GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) { 1120 GrGLuint id; 1121 GR_GL(GenBuffers(1, &id)); 1122 if (id) { 1123 GR_GL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id)); 1124 GrGLClearErr(); 1125 // make sure driver can allocate memory for this buffer 1126 GR_GL_NO_ERR(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, size, NULL, 1127 dynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW)); 1128 if (GrGLGetGLInterface()->fGetError() != GR_GL_NO_ERROR) { 1129 GR_GL(DeleteBuffers(1, &id)); 1130 // deleting bound buffer does implicit bind to 0 1131 fHWGeometryState.fIndexBuffer = NULL; 1132 return NULL; 1133 } 1134 GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, id, 1135 size, dynamic); 1136 fHWGeometryState.fIndexBuffer = indexBuffer; 1137 return indexBuffer; 1138 } 1139 return NULL; 1140 } 1141 1142 void GrGpuGL::flushScissor(const GrIRect* rect) { 1143 GrAssert(NULL != fCurrDrawState.fRenderTarget); 1144 const GrGLIRect& vp = 1145 ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport(); 1146 1147 GrGLIRect scissor; 1148 if (NULL != rect) { 1149 scissor.setRelativeTo(vp, rect->fLeft, rect->fTop, 1150 rect->width(), rect->height()); 1151 if (scissor.contains(vp)) { 1152 rect = NULL; 1153 } 1154 } 1155 1156 if (NULL != rect) { 1157 if (fHWBounds.fScissorRect != scissor) { 1158 scissor.pushToGLScissor(); 1159 fHWBounds.fScissorRect = scissor; 1160 } 1161 if (!fHWBounds.fScissorEnabled) { 1162 GR_GL(Enable(GR_GL_SCISSOR_TEST)); 1163 fHWBounds.fScissorEnabled = true; 1164 } 1165 } else { 1166 if (fHWBounds.fScissorEnabled) { 1167 GR_GL(Disable(GR_GL_SCISSOR_TEST)); 1168 fHWBounds.fScissorEnabled = false; 1169 } 1170 } 1171 } 1172 1173 void GrGpuGL::onClear(const GrIRect* rect, GrColor color) { 1174 if (NULL == fCurrDrawState.fRenderTarget) { 1175 return; 1176 } 1177 GrIRect r; 1178 if (NULL != rect) { 1179 // flushScissor expects rect to be clipped to the target. 1180 r = *rect; 1181 GrIRect rtRect = SkIRect::MakeWH(fCurrDrawState.fRenderTarget->width(), 1182 fCurrDrawState.fRenderTarget->height()); 1183 if (r.intersect(rtRect)) { 1184 rect = &r; 1185 } else { 1186 return; 1187 } 1188 } 1189 this->flushRenderTarget(rect); 1190 this->flushScissor(rect); 1191 GR_GL(ColorMask(GR_GL_TRUE,GR_GL_TRUE,GR_GL_TRUE,GR_GL_TRUE)); 1192 fHWDrawState.fFlagBits &= ~kNoColorWrites_StateBit; 1193 GR_GL(ClearColor(GrColorUnpackR(color)/255.f, 1194 GrColorUnpackG(color)/255.f, 1195 GrColorUnpackB(color)/255.f, 1196 GrColorUnpackA(color)/255.f)); 1197 GR_GL(Clear(GR_GL_COLOR_BUFFER_BIT)); 1198 } 1199 1200 void GrGpuGL::clearStencil(uint32_t value, uint32_t mask) { 1201 if (NULL == fCurrDrawState.fRenderTarget) { 1202 return; 1203 } 1204 1205 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1206 1207 if (fHWBounds.fScissorEnabled) { 1208 GR_GL(Disable(GR_GL_SCISSOR_TEST)); 1209 fHWBounds.fScissorEnabled = false; 1210 } 1211 GR_GL(StencilMask(mask)); 1212 GR_GL(ClearStencil(value)); 1213 GR_GL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 1214 fHWDrawState.fStencilSettings.invalidate(); 1215 } 1216 1217 void GrGpuGL::clearStencilClip(const GrIRect& rect) { 1218 GrAssert(NULL != fCurrDrawState.fRenderTarget); 1219 #if 0 1220 GrGLint stencilBitCount = fCurrDrawState.fRenderTarget->stencilBits(); 1221 GrAssert(stencilBitCount > 0); 1222 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); 1223 #else 1224 // we could just clear the clip bit but when we go through 1225 // angle a partial stencil mask will cause clears to be 1226 // turned into draws. Our contract on GrDrawTarget says that 1227 // changing the clip between stencil passes may or may not 1228 // zero the client's clip bits. So we just clear the whole thing. 1229 static const GrGLint clipStencilMask = ~0; 1230 #endif 1231 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1232 flushScissor(&rect); 1233 GR_GL(StencilMask(clipStencilMask)); 1234 GR_GL(ClearStencil(0)); 1235 GR_GL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 1236 fHWDrawState.fStencilSettings.invalidate(); 1237 } 1238 1239 void GrGpuGL::onForceRenderTargetFlush() { 1240 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1241 } 1242 1243 bool GrGpuGL::onReadPixels(GrRenderTarget* target, 1244 int left, int top, int width, int height, 1245 GrPixelConfig config, void* buffer) { 1246 GrGLenum internalFormat; // we don't use this for glReadPixels 1247 GrGLenum format; 1248 GrGLenum type; 1249 if (!this->canBeTexture(config, &internalFormat, &format, &type)) { 1250 return false; 1251 } 1252 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); 1253 GrAutoTPtrValueRestore<GrRenderTarget*> autoTargetRestore; 1254 switch (tgt->getResolveType()) { 1255 case GrGLRenderTarget::kCantResolve_ResolveType: 1256 return false; 1257 case GrGLRenderTarget::kAutoResolves_ResolveType: 1258 autoTargetRestore.save(&fCurrDrawState.fRenderTarget); 1259 fCurrDrawState.fRenderTarget = target; 1260 this->flushRenderTarget(&GrIRect::EmptyIRect()); 1261 break; 1262 case GrGLRenderTarget::kCanResolve_ResolveType: 1263 this->resolveRenderTarget(tgt); 1264 // we don't track the state of the READ FBO ID. 1265 GR_GL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, tgt->textureFBOID())); 1266 break; 1267 default: 1268 GrCrash("Unknown resolve type"); 1269 } 1270 1271 const GrGLIRect& glvp = tgt->getViewport(); 1272 1273 // the read rect is viewport-relative 1274 GrGLIRect readRect; 1275 readRect.setRelativeTo(glvp, left, top, width, height); 1276 GR_GL(ReadPixels(readRect.fLeft, readRect.fBottom, 1277 readRect.fWidth, readRect.fHeight, 1278 format, type, buffer)); 1279 1280 // now reverse the order of the rows, since GL's are bottom-to-top, but our 1281 // API presents top-to-bottom 1282 { 1283 size_t stride = width * GrBytesPerPixel(config); 1284 GrAutoMalloc rowStorage(stride); 1285 void* tmp = rowStorage.get(); 1286 1287 const int halfY = height >> 1; 1288 char* top = reinterpret_cast<char*>(buffer); 1289 char* bottom = top + (height - 1) * stride; 1290 for (int y = 0; y < halfY; y++) { 1291 memcpy(tmp, top, stride); 1292 memcpy(top, bottom, stride); 1293 memcpy(bottom, tmp, stride); 1294 top += stride; 1295 bottom -= stride; 1296 } 1297 } 1298 return true; 1299 } 1300 1301 void GrGpuGL::flushRenderTarget(const GrIRect* bound) { 1302 1303 GrAssert(NULL != fCurrDrawState.fRenderTarget); 1304 1305 GrGLRenderTarget* rt = (GrGLRenderTarget*)fCurrDrawState.fRenderTarget; 1306 if (fHWDrawState.fRenderTarget != fCurrDrawState.fRenderTarget) { 1307 GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID())); 1308 #if GR_COLLECT_STATS 1309 ++fStats.fRenderTargetChngCnt; 1310 #endif 1311 #if GR_DEBUG 1312 GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1313 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1314 GrPrintf("-- glCheckFramebufferStatus %x\n", status); 1315 } 1316 #endif 1317 fDirtyFlags.fRenderTargetChanged = true; 1318 fHWDrawState.fRenderTarget = fCurrDrawState.fRenderTarget; 1319 const GrGLIRect& vp = rt->getViewport(); 1320 if (fHWBounds.fViewportRect != vp) { 1321 vp.pushToGLViewport(); 1322 fHWBounds.fViewportRect = vp; 1323 } 1324 } 1325 if (NULL == bound || !bound->isEmpty()) { 1326 rt->flagAsNeedingResolve(bound); 1327 } 1328 } 1329 1330 GrGLenum gPrimitiveType2GLMode[] = { 1331 GR_GL_TRIANGLES, 1332 GR_GL_TRIANGLE_STRIP, 1333 GR_GL_TRIANGLE_FAN, 1334 GR_GL_POINTS, 1335 GR_GL_LINES, 1336 GR_GL_LINE_STRIP 1337 }; 1338 1339 #define SWAP_PER_DRAW 0 1340 1341 #if SWAP_PER_DRAW 1342 #if GR_MAC_BUILD 1343 #include <AGL/agl.h> 1344 #elif GR_WIN32_BUILD 1345 void SwapBuf() { 1346 DWORD procID = GetCurrentProcessId(); 1347 HWND hwnd = GetTopWindow(GetDesktopWindow()); 1348 while(hwnd) { 1349 DWORD wndProcID = 0; 1350 GetWindowThreadProcessId(hwnd, &wndProcID); 1351 if(wndProcID == procID) { 1352 SwapBuffers(GetDC(hwnd)); 1353 } 1354 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); 1355 } 1356 } 1357 #endif 1358 #endif 1359 1360 void GrGpuGL::onDrawIndexed(GrPrimitiveType type, 1361 uint32_t startVertex, 1362 uint32_t startIndex, 1363 uint32_t vertexCount, 1364 uint32_t indexCount) { 1365 GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode)); 1366 1367 GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * startIndex); 1368 1369 GrAssert(NULL != fHWGeometryState.fIndexBuffer); 1370 GrAssert(NULL != fHWGeometryState.fVertexBuffer); 1371 1372 // our setupGeometry better have adjusted this to zero since 1373 // DrawElements always draws from the begining of the arrays for idx 0. 1374 GrAssert(0 == startVertex); 1375 1376 GR_GL(DrawElements(gPrimitiveType2GLMode[type], indexCount, 1377 GR_GL_UNSIGNED_SHORT, indices)); 1378 #if SWAP_PER_DRAW 1379 glFlush(); 1380 #if GR_MAC_BUILD 1381 aglSwapBuffers(aglGetCurrentContext()); 1382 int set_a_break_pt_here = 9; 1383 aglSwapBuffers(aglGetCurrentContext()); 1384 #elif GR_WIN32_BUILD 1385 SwapBuf(); 1386 int set_a_break_pt_here = 9; 1387 SwapBuf(); 1388 #endif 1389 #endif 1390 } 1391 1392 void GrGpuGL::onDrawNonIndexed(GrPrimitiveType type, 1393 uint32_t startVertex, 1394 uint32_t vertexCount) { 1395 GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode)); 1396 1397 GrAssert(NULL != fHWGeometryState.fVertexBuffer); 1398 1399 // our setupGeometry better have adjusted this to zero. 1400 // DrawElements doesn't take an offset so we always adjus the startVertex. 1401 GrAssert(0 == startVertex); 1402 1403 // pass 0 for parameter first. We have to adjust gl*Pointer() to 1404 // account for startVertex in the DrawElements case. So we always 1405 // rely on setupGeometry to have accounted for startVertex. 1406 GR_GL(DrawArrays(gPrimitiveType2GLMode[type], 0, vertexCount)); 1407 #if SWAP_PER_DRAW 1408 glFlush(); 1409 #if GR_MAC_BUILD 1410 aglSwapBuffers(aglGetCurrentContext()); 1411 int set_a_break_pt_here = 9; 1412 aglSwapBuffers(aglGetCurrentContext()); 1413 #elif GR_WIN32_BUILD 1414 SwapBuf(); 1415 int set_a_break_pt_here = 9; 1416 SwapBuf(); 1417 #endif 1418 #endif 1419 } 1420 1421 void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) { 1422 1423 if (rt->needsResolve()) { 1424 GrAssert(kNone_MSFBO != fMSFBOType); 1425 GrAssert(rt->textureFBOID() != rt->renderFBOID()); 1426 GR_GL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, 1427 rt->renderFBOID())); 1428 GR_GL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, 1429 rt->textureFBOID())); 1430 #if GR_COLLECT_STATS 1431 ++fStats.fRenderTargetChngCnt; 1432 #endif 1433 // make sure we go through flushRenderTarget() since we've modified 1434 // the bound DRAW FBO ID. 1435 fHWDrawState.fRenderTarget = NULL; 1436 const GrGLIRect& vp = rt->getViewport(); 1437 const GrIRect dirtyRect = rt->getResolveRect(); 1438 GrGLIRect r; 1439 r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop, 1440 dirtyRect.width(), dirtyRect.height()); 1441 1442 if (kAppleES_MSFBO == fMSFBOType) { 1443 // Apple's extension uses the scissor as the blit bounds. 1444 GR_GL(Enable(GR_GL_SCISSOR_TEST)); 1445 GR_GL(Scissor(r.fLeft, r.fBottom, 1446 r.fWidth, r.fHeight)); 1447 GR_GL(ResolveMultisampleFramebuffer()); 1448 fHWBounds.fScissorRect.invalidate(); 1449 fHWBounds.fScissorEnabled = true; 1450 } else { 1451 if (kDesktopARB_MSFBO != fMSFBOType) { 1452 // this respects the scissor during the blit, so disable it. 1453 GrAssert(kDesktopEXT_MSFBO == fMSFBOType); 1454 flushScissor(NULL); 1455 } 1456 int right = r.fLeft + r.fWidth; 1457 int top = r.fBottom + r.fHeight; 1458 GR_GL(BlitFramebuffer(r.fLeft, r.fBottom, right, top, 1459 r.fLeft, r.fBottom, right, top, 1460 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 1461 } 1462 rt->flagAsResolved(); 1463 } 1464 } 1465 1466 static const GrGLenum grToGLStencilFunc[] = { 1467 GR_GL_ALWAYS, // kAlways_StencilFunc 1468 GR_GL_NEVER, // kNever_StencilFunc 1469 GR_GL_GREATER, // kGreater_StencilFunc 1470 GR_GL_GEQUAL, // kGEqual_StencilFunc 1471 GR_GL_LESS, // kLess_StencilFunc 1472 GR_GL_LEQUAL, // kLEqual_StencilFunc, 1473 GR_GL_EQUAL, // kEqual_StencilFunc, 1474 GR_GL_NOTEQUAL, // kNotEqual_StencilFunc, 1475 }; 1476 GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilFunc) == kBasicStencilFuncCount); 1477 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); 1478 GR_STATIC_ASSERT(1 == kNever_StencilFunc); 1479 GR_STATIC_ASSERT(2 == kGreater_StencilFunc); 1480 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc); 1481 GR_STATIC_ASSERT(4 == kLess_StencilFunc); 1482 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc); 1483 GR_STATIC_ASSERT(6 == kEqual_StencilFunc); 1484 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc); 1485 1486 static const GrGLenum grToGLStencilOp[] = { 1487 GR_GL_KEEP, // kKeep_StencilOp 1488 GR_GL_REPLACE, // kReplace_StencilOp 1489 GR_GL_INCR_WRAP, // kIncWrap_StencilOp 1490 GR_GL_INCR, // kIncClamp_StencilOp 1491 GR_GL_DECR_WRAP, // kDecWrap_StencilOp 1492 GR_GL_DECR, // kDecClamp_StencilOp 1493 GR_GL_ZERO, // kZero_StencilOp 1494 GR_GL_INVERT, // kInvert_StencilOp 1495 }; 1496 GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilOp) == kStencilOpCount); 1497 GR_STATIC_ASSERT(0 == kKeep_StencilOp); 1498 GR_STATIC_ASSERT(1 == kReplace_StencilOp); 1499 GR_STATIC_ASSERT(2 == kIncWrap_StencilOp); 1500 GR_STATIC_ASSERT(3 == kIncClamp_StencilOp); 1501 GR_STATIC_ASSERT(4 == kDecWrap_StencilOp); 1502 GR_STATIC_ASSERT(5 == kDecClamp_StencilOp); 1503 GR_STATIC_ASSERT(6 == kZero_StencilOp); 1504 GR_STATIC_ASSERT(7 == kInvert_StencilOp); 1505 1506 void GrGpuGL::flushStencil() { 1507 const GrStencilSettings* settings = &fCurrDrawState.fStencilSettings; 1508 1509 // use stencil for clipping if clipping is enabled and the clip 1510 // has been written into the stencil. 1511 bool stencilClip = fClipState.fClipInStencil && 1512 (kClip_StateBit & fCurrDrawState.fFlagBits); 1513 bool stencilChange = fHWStencilClip != stencilClip || 1514 fHWDrawState.fStencilSettings != *settings || 1515 ((fHWDrawState.fFlagBits & kModifyStencilClip_StateBit) != 1516 (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit)); 1517 1518 if (stencilChange) { 1519 1520 // we can't simultaneously perform stencil-clipping and modify the stencil clip 1521 GrAssert(!stencilClip || !(fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit)); 1522 1523 if (settings->isDisabled()) { 1524 if (stencilClip) { 1525 settings = &gClipStencilSettings; 1526 } 1527 } 1528 1529 if (settings->isDisabled()) { 1530 GR_GL(Disable(GR_GL_STENCIL_TEST)); 1531 } else { 1532 GR_GL(Enable(GR_GL_STENCIL_TEST)); 1533 #if GR_DEBUG 1534 if (!fStencilWrapOpsSupport) { 1535 GrAssert(settings->fFrontPassOp != kIncWrap_StencilOp); 1536 GrAssert(settings->fFrontPassOp != kDecWrap_StencilOp); 1537 GrAssert(settings->fFrontFailOp != kIncWrap_StencilOp); 1538 GrAssert(settings->fBackFailOp != kDecWrap_StencilOp); 1539 GrAssert(settings->fBackPassOp != kIncWrap_StencilOp); 1540 GrAssert(settings->fBackPassOp != kDecWrap_StencilOp); 1541 GrAssert(settings->fBackFailOp != kIncWrap_StencilOp); 1542 GrAssert(settings->fFrontFailOp != kDecWrap_StencilOp); 1543 } 1544 #endif 1545 int stencilBits = fCurrDrawState.fRenderTarget->stencilBits(); 1546 GrAssert(stencilBits || 1547 (GrStencilSettings::gDisabled == 1548 fCurrDrawState.fStencilSettings)); 1549 GrGLuint clipStencilMask = 1 << (stencilBits - 1); 1550 GrGLuint userStencilMask = clipStencilMask - 1; 1551 1552 unsigned int frontRef = settings->fFrontFuncRef; 1553 unsigned int frontMask = settings->fFrontFuncMask; 1554 unsigned int frontWriteMask = settings->fFrontWriteMask; 1555 GrGLenum frontFunc; 1556 1557 if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) { 1558 1559 GrAssert(settings->fFrontFunc < kBasicStencilFuncCount); 1560 frontFunc = grToGLStencilFunc[settings->fFrontFunc]; 1561 } else { 1562 frontFunc = grToGLStencilFunc[ConvertStencilFunc(stencilClip, settings->fFrontFunc)]; 1563 1564 ConvertStencilFuncAndMask(settings->fFrontFunc, 1565 stencilClip, 1566 clipStencilMask, 1567 userStencilMask, 1568 &frontRef, 1569 &frontMask); 1570 frontWriteMask &= userStencilMask; 1571 } 1572 GrAssert(settings->fFrontFailOp >= 0 && 1573 (unsigned) settings->fFrontFailOp < GR_ARRAY_COUNT(grToGLStencilOp)); 1574 GrAssert(settings->fFrontPassOp >= 0 && 1575 (unsigned) settings->fFrontPassOp < GR_ARRAY_COUNT(grToGLStencilOp)); 1576 GrAssert(settings->fBackFailOp >= 0 && 1577 (unsigned) settings->fBackFailOp < GR_ARRAY_COUNT(grToGLStencilOp)); 1578 GrAssert(settings->fBackPassOp >= 0 && 1579 (unsigned) settings->fBackPassOp < GR_ARRAY_COUNT(grToGLStencilOp)); 1580 if (fTwoSidedStencilSupport) { 1581 GrGLenum backFunc; 1582 1583 unsigned int backRef = settings->fBackFuncRef; 1584 unsigned int backMask = settings->fBackFuncMask; 1585 unsigned int backWriteMask = settings->fBackWriteMask; 1586 1587 1588 if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) { 1589 GrAssert(settings->fBackFunc < kBasicStencilFuncCount); 1590 backFunc = grToGLStencilFunc[settings->fBackFunc]; 1591 } else { 1592 backFunc = grToGLStencilFunc[ConvertStencilFunc(stencilClip, settings->fBackFunc)]; 1593 ConvertStencilFuncAndMask(settings->fBackFunc, 1594 stencilClip, 1595 clipStencilMask, 1596 userStencilMask, 1597 &backRef, 1598 &backMask); 1599 backWriteMask &= userStencilMask; 1600 } 1601 1602 GR_GL(StencilFuncSeparate(GR_GL_FRONT, frontFunc, frontRef, frontMask)); 1603 GR_GL(StencilMaskSeparate(GR_GL_FRONT, frontWriteMask)); 1604 GR_GL(StencilFuncSeparate(GR_GL_BACK, backFunc, backRef, backMask)); 1605 GR_GL(StencilMaskSeparate(GR_GL_BACK, backWriteMask)); 1606 GR_GL(StencilOpSeparate(GR_GL_FRONT, grToGLStencilOp[settings->fFrontFailOp], 1607 grToGLStencilOp[settings->fFrontPassOp], 1608 grToGLStencilOp[settings->fFrontPassOp])); 1609 1610 GR_GL(StencilOpSeparate(GR_GL_BACK, grToGLStencilOp[settings->fBackFailOp], 1611 grToGLStencilOp[settings->fBackPassOp], 1612 grToGLStencilOp[settings->fBackPassOp])); 1613 } else { 1614 GR_GL(StencilFunc(frontFunc, frontRef, frontMask)); 1615 GR_GL(StencilMask(frontWriteMask)); 1616 GR_GL(StencilOp(grToGLStencilOp[settings->fFrontFailOp], 1617 grToGLStencilOp[settings->fFrontPassOp], 1618 grToGLStencilOp[settings->fFrontPassOp])); 1619 } 1620 } 1621 fHWDrawState.fStencilSettings = fCurrDrawState.fStencilSettings; 1622 fHWStencilClip = stencilClip; 1623 } 1624 } 1625 1626 bool GrGpuGL::useSmoothLines() { 1627 // there is a conflict between using smooth lines and our use of 1628 // premultiplied alpha. Smooth lines tweak the incoming alpha value 1629 // but not in a premul-alpha way. So we only use them when our alpha 1630 // is 0xff. 1631 1632 // TODO: write a smarter line frag shader. 1633 1634 return (kAntialias_StateBit & fCurrDrawState.fFlagBits) && 1635 canDisableBlend(); 1636 } 1637 1638 void GrGpuGL::flushAAState(GrPrimitiveType type) { 1639 if (GR_GL_SUPPORT_DESKTOP) { 1640 // ES doesn't support toggling GL_MULTISAMPLE and doesn't have 1641 // smooth lines. 1642 1643 // we prefer smooth lines over multisampled lines 1644 // msaa should be disabled if drawing smooth lines. 1645 if (GrIsPrimTypeLines(type)) { 1646 bool smooth = useSmoothLines(); 1647 if (!fHWAAState.fSmoothLineEnabled && smooth) { 1648 GR_GL(Enable(GR_GL_LINE_SMOOTH)); 1649 fHWAAState.fSmoothLineEnabled = true; 1650 } else if (fHWAAState.fSmoothLineEnabled && !smooth) { 1651 GR_GL(Disable(GR_GL_LINE_SMOOTH)); 1652 fHWAAState.fSmoothLineEnabled = false; 1653 } 1654 if (fCurrDrawState.fRenderTarget->isMultisampled() && 1655 fHWAAState.fMSAAEnabled) { 1656 GR_GL(Disable(GR_GL_MULTISAMPLE)); 1657 fHWAAState.fMSAAEnabled = false; 1658 } 1659 } else if (fCurrDrawState.fRenderTarget->isMultisampled() && 1660 !!(kAntialias_StateBit & fCurrDrawState.fFlagBits) != 1661 fHWAAState.fMSAAEnabled) { 1662 if (fHWAAState.fMSAAEnabled) { 1663 GR_GL(Disable(GR_GL_MULTISAMPLE)); 1664 fHWAAState.fMSAAEnabled = false; 1665 } else { 1666 GR_GL(Enable(GR_GL_MULTISAMPLE)); 1667 fHWAAState.fMSAAEnabled = true; 1668 } 1669 } 1670 } 1671 } 1672 1673 void GrGpuGL::flushBlend(GrPrimitiveType type, 1674 GrBlendCoeff srcCoeff, 1675 GrBlendCoeff dstCoeff) { 1676 if (GrIsPrimTypeLines(type) && useSmoothLines()) { 1677 if (fHWBlendDisabled) { 1678 GR_GL(Enable(GR_GL_BLEND)); 1679 fHWBlendDisabled = false; 1680 } 1681 if (kSA_BlendCoeff != fHWDrawState.fSrcBlend || 1682 kISA_BlendCoeff != fHWDrawState.fDstBlend) { 1683 GR_GL(BlendFunc(gXfermodeCoeff2Blend[kSA_BlendCoeff], 1684 gXfermodeCoeff2Blend[kISA_BlendCoeff])); 1685 fHWDrawState.fSrcBlend = kSA_BlendCoeff; 1686 fHWDrawState.fDstBlend = kISA_BlendCoeff; 1687 } 1688 } else { 1689 bool blendOff = canDisableBlend(); 1690 if (fHWBlendDisabled != blendOff) { 1691 if (blendOff) { 1692 GR_GL(Disable(GR_GL_BLEND)); 1693 } else { 1694 GR_GL(Enable(GR_GL_BLEND)); 1695 } 1696 fHWBlendDisabled = blendOff; 1697 } 1698 if (!blendOff) { 1699 if (fHWDrawState.fSrcBlend != srcCoeff || 1700 fHWDrawState.fDstBlend != dstCoeff) { 1701 GR_GL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], 1702 gXfermodeCoeff2Blend[dstCoeff])); 1703 fHWDrawState.fSrcBlend = srcCoeff; 1704 fHWDrawState.fDstBlend = dstCoeff; 1705 } 1706 if ((BlendCoeffReferencesConstant(srcCoeff) || 1707 BlendCoeffReferencesConstant(dstCoeff)) && 1708 fHWDrawState.fBlendConstant != fCurrDrawState.fBlendConstant) { 1709 1710 float c[] = { 1711 GrColorUnpackR(fCurrDrawState.fBlendConstant) / 255.f, 1712 GrColorUnpackG(fCurrDrawState.fBlendConstant) / 255.f, 1713 GrColorUnpackB(fCurrDrawState.fBlendConstant) / 255.f, 1714 GrColorUnpackA(fCurrDrawState.fBlendConstant) / 255.f 1715 }; 1716 GR_GL(BlendColor(c[0], c[1], c[2], c[3])); 1717 fHWDrawState.fBlendConstant = fCurrDrawState.fBlendConstant; 1718 } 1719 } 1720 } 1721 } 1722 1723 bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { 1724 1725 // GrGpu::setupClipAndFlushState should have already checked this 1726 // and bailed if not true. 1727 GrAssert(NULL != fCurrDrawState.fRenderTarget); 1728 1729 for (int s = 0; s < kNumStages; ++s) { 1730 // bind texture and set sampler state 1731 if (this->isStageEnabled(s)) { 1732 GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTextures[s]; 1733 1734 // true for now, but maybe not with GrEffect. 1735 GrAssert(NULL != nextTexture); 1736 // if we created a rt/tex and rendered to it without using a 1737 // texture and now we're texuring from the rt it will still be 1738 // the last bound texture, but it needs resolving. So keep this 1739 // out of the "last != next" check. 1740 GrGLRenderTarget* texRT = 1741 static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget()); 1742 if (NULL != texRT) { 1743 resolveRenderTarget(texRT); 1744 } 1745 1746 if (fHWDrawState.fTextures[s] != nextTexture) { 1747 setTextureUnit(s); 1748 GR_GL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID())); 1749 #if GR_COLLECT_STATS 1750 ++fStats.fTextureChngCnt; 1751 #endif 1752 //GrPrintf("---- bindtexture %d\n", nextTexture->textureID()); 1753 fHWDrawState.fTextures[s] = nextTexture; 1754 } 1755 1756 const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s]; 1757 const GrGLTexture::TexParams& oldTexParams = 1758 nextTexture->getTexParams(); 1759 GrGLTexture::TexParams newTexParams; 1760 1761 if (GrSamplerState::kNearest_Filter == sampler.getFilter()) { 1762 newTexParams.fFilter = GR_GL_NEAREST; 1763 } else { 1764 newTexParams.fFilter = GR_GL_LINEAR; 1765 } 1766 1767 newTexParams.fWrapS = 1768 GrGLTexture::WrapMode2GLWrap()[sampler.getWrapX()]; 1769 newTexParams.fWrapT = 1770 GrGLTexture::WrapMode2GLWrap()[sampler.getWrapY()]; 1771 1772 if (newTexParams.fFilter != oldTexParams.fFilter) { 1773 setTextureUnit(s); 1774 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 1775 GR_GL_TEXTURE_MAG_FILTER, 1776 newTexParams.fFilter)); 1777 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 1778 GR_GL_TEXTURE_MIN_FILTER, 1779 newTexParams.fFilter)); 1780 } 1781 if (newTexParams.fWrapS != oldTexParams.fWrapS) { 1782 setTextureUnit(s); 1783 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 1784 GR_GL_TEXTURE_WRAP_S, 1785 newTexParams.fWrapS)); 1786 } 1787 if (newTexParams.fWrapT != oldTexParams.fWrapT) { 1788 setTextureUnit(s); 1789 GR_GL(TexParameteri(GR_GL_TEXTURE_2D, 1790 GR_GL_TEXTURE_WRAP_T, 1791 newTexParams.fWrapT)); 1792 } 1793 nextTexture->setTexParams(newTexParams); 1794 1795 // The texture matrix has to compensate for texture width/height 1796 // and NPOT-embedded-in-POT 1797 fDirtyFlags.fTextureChangedMask |= (1 << s); 1798 } 1799 } 1800 1801 GrIRect* rect = NULL; 1802 GrIRect clipBounds; 1803 if ((fCurrDrawState.fFlagBits & kClip_StateBit) && 1804 fClip.hasConservativeBounds()) { 1805 fClip.getConservativeBounds().roundOut(&clipBounds); 1806 rect = &clipBounds; 1807 } 1808 this->flushRenderTarget(rect); 1809 this->flushAAState(type); 1810 1811 if ((fCurrDrawState.fFlagBits & kDither_StateBit) != 1812 (fHWDrawState.fFlagBits & kDither_StateBit)) { 1813 if (fCurrDrawState.fFlagBits & kDither_StateBit) { 1814 GR_GL(Enable(GR_GL_DITHER)); 1815 } else { 1816 GR_GL(Disable(GR_GL_DITHER)); 1817 } 1818 } 1819 1820 if ((fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) != 1821 (fHWDrawState.fFlagBits & kNoColorWrites_StateBit)) { 1822 GrGLenum mask; 1823 if (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) { 1824 mask = GR_GL_FALSE; 1825 } else { 1826 mask = GR_GL_TRUE; 1827 } 1828 GR_GL(ColorMask(mask, mask, mask, mask)); 1829 } 1830 1831 if (fHWDrawState.fDrawFace != fCurrDrawState.fDrawFace) { 1832 switch (fCurrDrawState.fDrawFace) { 1833 case kCCW_DrawFace: 1834 GR_GL(Enable(GR_GL_CULL_FACE)); 1835 GR_GL(CullFace(GR_GL_BACK)); 1836 break; 1837 case kCW_DrawFace: 1838 GR_GL(Enable(GR_GL_CULL_FACE)); 1839 GR_GL(CullFace(GR_GL_FRONT)); 1840 break; 1841 case kBoth_DrawFace: 1842 GR_GL(Disable(GR_GL_CULL_FACE)); 1843 break; 1844 default: 1845 GrCrash("Unknown draw face."); 1846 } 1847 fHWDrawState.fDrawFace = fCurrDrawState.fDrawFace; 1848 } 1849 1850 #if GR_DEBUG 1851 // check for circular rendering 1852 for (int s = 0; s < kNumStages; ++s) { 1853 GrAssert(!this->isStageEnabled(s) || 1854 NULL == fCurrDrawState.fRenderTarget || 1855 NULL == fCurrDrawState.fTextures[s] || 1856 fCurrDrawState.fTextures[s]->asRenderTarget() != 1857 fCurrDrawState.fRenderTarget); 1858 } 1859 #endif 1860 1861 flushStencil(); 1862 1863 // flushStencil may look at the private state bits, so keep it before this. 1864 fHWDrawState.fFlagBits = fCurrDrawState.fFlagBits; 1865 return true; 1866 } 1867 1868 void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) { 1869 if (fHWGeometryState.fVertexBuffer != buffer) { 1870 fHWGeometryState.fArrayPtrsDirty = true; 1871 fHWGeometryState.fVertexBuffer = buffer; 1872 } 1873 } 1874 1875 void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) { 1876 if (fHWGeometryState.fVertexBuffer == buffer) { 1877 // deleting bound buffer does implied bind to 0 1878 fHWGeometryState.fVertexBuffer = NULL; 1879 fHWGeometryState.fArrayPtrsDirty = true; 1880 } 1881 } 1882 1883 void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) { 1884 fGeometrySrc.fIndexBuffer = buffer; 1885 } 1886 1887 void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) { 1888 if (fHWGeometryState.fIndexBuffer == buffer) { 1889 // deleting bound buffer does implied bind to 0 1890 fHWGeometryState.fIndexBuffer = NULL; 1891 } 1892 } 1893 1894 void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { 1895 GrAssert(NULL != renderTarget); 1896 if (fCurrDrawState.fRenderTarget == renderTarget) { 1897 fCurrDrawState.fRenderTarget = NULL; 1898 } 1899 if (fHWDrawState.fRenderTarget == renderTarget) { 1900 fHWDrawState.fRenderTarget = NULL; 1901 } 1902 } 1903 1904 void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { 1905 for (int s = 0; s < kNumStages; ++s) { 1906 if (fCurrDrawState.fTextures[s] == texture) { 1907 fCurrDrawState.fTextures[s] = NULL; 1908 } 1909 if (fHWDrawState.fTextures[s] == texture) { 1910 // deleting bound texture does implied bind to 0 1911 fHWDrawState.fTextures[s] = NULL; 1912 } 1913 } 1914 } 1915 1916 bool GrGpuGL::canBeTexture(GrPixelConfig config, 1917 GrGLenum* internalFormat, 1918 GrGLenum* format, 1919 GrGLenum* type) { 1920 switch (config) { 1921 case kRGBA_8888_GrPixelConfig: 1922 case kRGBX_8888_GrPixelConfig: // todo: can we tell it our X? 1923 *format = GR_GL_32BPP_COLOR_FORMAT; 1924 if (GR_GL_SUPPORT_ES) { 1925 // according to GL_EXT_texture_format_BGRA8888 the *internal* 1926 // format for a BGRA is BGRA not RGBA (as on desktop) 1927 *internalFormat = GR_GL_32BPP_COLOR_FORMAT; 1928 } else { 1929 *internalFormat = GR_GL_RGBA; 1930 } 1931 *type = GR_GL_UNSIGNED_BYTE; 1932 break; 1933 case kRGB_565_GrPixelConfig: 1934 *format = GR_GL_RGB; 1935 *internalFormat = GR_GL_RGB; 1936 *type = GR_GL_UNSIGNED_SHORT_5_6_5; 1937 break; 1938 case kRGBA_4444_GrPixelConfig: 1939 *format = GR_GL_RGBA; 1940 *internalFormat = GR_GL_RGBA; 1941 *type = GR_GL_UNSIGNED_SHORT_4_4_4_4; 1942 break; 1943 case kIndex_8_GrPixelConfig: 1944 if (this->supports8BitPalette()) { 1945 *format = GR_GL_PALETTE8_RGBA8; 1946 *internalFormat = GR_GL_PALETTE8_RGBA8; 1947 *type = GR_GL_UNSIGNED_BYTE; // unused I think 1948 } else { 1949 return false; 1950 } 1951 break; 1952 case kAlpha_8_GrPixelConfig: 1953 *format = GR_GL_ALPHA; 1954 *internalFormat = GR_GL_ALPHA; 1955 *type = GR_GL_UNSIGNED_BYTE; 1956 break; 1957 default: 1958 return false; 1959 } 1960 return true; 1961 } 1962 1963 void GrGpuGL::setTextureUnit(int unit) { 1964 GrAssert(unit >= 0 && unit < kNumStages); 1965 if (fActiveTextureUnitIdx != unit) { 1966 GR_GL(ActiveTexture(GR_GL_TEXTURE0 + unit)); 1967 fActiveTextureUnitIdx = unit; 1968 } 1969 } 1970 1971 void GrGpuGL::setSpareTextureUnit() { 1972 if (fActiveTextureUnitIdx != (GR_GL_TEXTURE0 + SPARE_TEX_UNIT)) { 1973 GR_GL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); 1974 fActiveTextureUnitIdx = SPARE_TEX_UNIT; 1975 } 1976 } 1977 1978 /* On ES the internalFormat and format must match for TexImage and we use 1979 GL_RGB, GL_RGBA for color formats. We also generally like having the driver 1980 decide the internalFormat. However, on ES internalFormat for 1981 RenderBufferStorage* has to be a specific format (not a base format like 1982 GL_RGBA). 1983 */ 1984 bool GrGpuGL::fboInternalFormat(GrPixelConfig config, GrGLenum* format) { 1985 switch (config) { 1986 case kRGBA_8888_GrPixelConfig: 1987 case kRGBX_8888_GrPixelConfig: 1988 if (fRGBA8Renderbuffer) { 1989 *format = GR_GL_RGBA8; 1990 return true; 1991 } else { 1992 return false; 1993 } 1994 case kRGB_565_GrPixelConfig: 1995 GrAssert(GR_GL_SUPPORT_ES); // ES2 supports 565. ES1 supports it 1996 // with FBO extension desktop GL has 1997 // no such internal format 1998 *format = GR_GL_RGB565; 1999 return true; 2000 case kRGBA_4444_GrPixelConfig: 2001 *format = GR_GL_RGBA4; 2002 return true; 2003 default: 2004 return false; 2005 } 2006 } 2007 2008 void GrGpuGL::resetDirtyFlags() { 2009 Gr_bzero(&fDirtyFlags, sizeof(fDirtyFlags)); 2010 } 2011 2012 void GrGpuGL::setBuffers(bool indexed, 2013 int* extraVertexOffset, 2014 int* extraIndexOffset) { 2015 2016 GrAssert(NULL != extraVertexOffset); 2017 2018 GrGLVertexBuffer* vbuf; 2019 switch (fGeometrySrc.fVertexSrc) { 2020 case kBuffer_GeometrySrcType: 2021 *extraVertexOffset = 0; 2022 vbuf = (GrGLVertexBuffer*) fGeometrySrc.fVertexBuffer; 2023 break; 2024 case kArray_GeometrySrcType: 2025 case kReserved_GeometrySrcType: 2026 finalizeReservedVertices(); 2027 *extraVertexOffset = fCurrPoolStartVertex; 2028 vbuf = (GrGLVertexBuffer*) fCurrPoolVertexBuffer; 2029 break; 2030 default: 2031 vbuf = NULL; // suppress warning 2032 GrCrash("Unknown geometry src type!"); 2033 } 2034 2035 GrAssert(NULL != vbuf); 2036 GrAssert(!vbuf->isLocked()); 2037 if (fHWGeometryState.fVertexBuffer != vbuf) { 2038 GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, vbuf->bufferID())); 2039 fHWGeometryState.fArrayPtrsDirty = true; 2040 fHWGeometryState.fVertexBuffer = vbuf; 2041 } 2042 2043 if (indexed) { 2044 GrAssert(NULL != extraIndexOffset); 2045 2046 GrGLIndexBuffer* ibuf; 2047 switch (fGeometrySrc.fIndexSrc) { 2048 case kBuffer_GeometrySrcType: 2049 *extraIndexOffset = 0; 2050 ibuf = (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer; 2051 break; 2052 case kArray_GeometrySrcType: 2053 case kReserved_GeometrySrcType: 2054 finalizeReservedIndices(); 2055 *extraIndexOffset = fCurrPoolStartIndex; 2056 ibuf = (GrGLIndexBuffer*) fCurrPoolIndexBuffer; 2057 break; 2058 default: 2059 ibuf = NULL; // suppress warning 2060 GrCrash("Unknown geometry src type!"); 2061 } 2062 2063 GrAssert(NULL != ibuf); 2064 GrAssert(!ibuf->isLocked()); 2065 if (fHWGeometryState.fIndexBuffer != ibuf) { 2066 GR_GL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibuf->bufferID())); 2067 fHWGeometryState.fIndexBuffer = ibuf; 2068 } 2069 } 2070 } 2071 2072 int GrGpuGL::getMaxEdges() const { 2073 // FIXME: This is a pessimistic estimate based on how many other things 2074 // want to add uniforms. This should be centralized somewhere. 2075 return GR_CT_MIN(fMaxFragmentUniformVectors - 8, kMaxEdges); 2076 } 2077