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