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 "GrGLNameAllocator.h" 11#include "GrGLStencilBuffer.h" 12#include "GrGLPath.h" 13#include "GrGLShaderBuilder.h" 14#include "GrTemplates.h" 15#include "GrTypes.h" 16#include "SkStrokeRec.h" 17#include "SkTemplates.h" 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#define SKIP_CACHE_CHECK true 23 24#if GR_GL_CHECK_ALLOC_WITH_GET_ERROR 25 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) 26 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) 27 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) 28#else 29 #define CLEAR_ERROR_BEFORE_ALLOC(iface) 30 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call) 31 #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR 32#endif 33 34 35/////////////////////////////////////////////////////////////////////////////// 36 37static const GrGLenum gXfermodeCoeff2Blend[] = { 38 GR_GL_ZERO, 39 GR_GL_ONE, 40 GR_GL_SRC_COLOR, 41 GR_GL_ONE_MINUS_SRC_COLOR, 42 GR_GL_DST_COLOR, 43 GR_GL_ONE_MINUS_DST_COLOR, 44 GR_GL_SRC_ALPHA, 45 GR_GL_ONE_MINUS_SRC_ALPHA, 46 GR_GL_DST_ALPHA, 47 GR_GL_ONE_MINUS_DST_ALPHA, 48 GR_GL_CONSTANT_COLOR, 49 GR_GL_ONE_MINUS_CONSTANT_COLOR, 50 GR_GL_CONSTANT_ALPHA, 51 GR_GL_ONE_MINUS_CONSTANT_ALPHA, 52 53 // extended blend coeffs 54 GR_GL_SRC1_COLOR, 55 GR_GL_ONE_MINUS_SRC1_COLOR, 56 GR_GL_SRC1_ALPHA, 57 GR_GL_ONE_MINUS_SRC1_ALPHA, 58}; 59 60bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { 61 static const bool gCoeffReferencesBlendConst[] = { 62 false, 63 false, 64 false, 65 false, 66 false, 67 false, 68 false, 69 false, 70 false, 71 false, 72 true, 73 true, 74 true, 75 true, 76 77 // extended blend coeffs 78 false, 79 false, 80 false, 81 false, 82 }; 83 return gCoeffReferencesBlendConst[coeff]; 84 GR_STATIC_ASSERT(kTotalGrBlendCoeffCount == 85 SK_ARRAY_COUNT(gCoeffReferencesBlendConst)); 86 87 GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff); 88 GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff); 89 GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff); 90 GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff); 91 GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff); 92 GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff); 93 GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff); 94 GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff); 95 GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff); 96 GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff); 97 GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff); 98 GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff); 99 GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff); 100 GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff); 101 102 GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff); 103 GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff); 104 GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff); 105 GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff); 106 107 // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope 108 GR_STATIC_ASSERT(kTotalGrBlendCoeffCount == 109 SK_ARRAY_COUNT(gXfermodeCoeff2Blend)); 110} 111 112/////////////////////////////////////////////////////////////////////////////// 113 114static bool gPrintStartupSpew; 115 116GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) 117 : GrGpu(context) 118 , fGLContext(ctx) { 119 120 SkASSERT(ctx.isInitialized()); 121 fCaps.reset(SkRef(ctx.caps())); 122 123 fHWBoundTextures.reset(this->glCaps().maxFragmentTextureUnits()); 124 fHWPathTexGenSettings.reset(this->glCaps().maxFixedFunctionTextureCoords()); 125 126 GrGLClearErr(fGLContext.interface()); 127 if (gPrintStartupSpew) { 128 const GrGLubyte* vendor; 129 const GrGLubyte* renderer; 130 const GrGLubyte* version; 131 GL_CALL_RET(vendor, GetString(GR_GL_VENDOR)); 132 GL_CALL_RET(renderer, GetString(GR_GL_RENDERER)); 133 GL_CALL_RET(version, GetString(GR_GL_VERSION)); 134 GrPrintf("------------------------- create GrGpuGL %p --------------\n", 135 this); 136 GrPrintf("------ VENDOR %s\n", vendor); 137 GrPrintf("------ RENDERER %s\n", renderer); 138 GrPrintf("------ VERSION %s\n", version); 139 GrPrintf("------ EXTENSIONS\n"); 140#if 0 // TODO: Reenable this after GrGLInterface's extensions can be accessed safely. 141 ctx.extensions().print(); 142#endif 143 GrPrintf("\n"); 144 GrPrintf(this->glCaps().dump().c_str()); 145 } 146 147 fProgramCache = SkNEW_ARGS(ProgramCache, (this)); 148 149 SkASSERT(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt); 150 151 fLastSuccessfulStencilFmtIdx = 0; 152 fHWProgramID = 0; 153} 154 155GrGpuGL::~GrGpuGL() { 156 if (0 != fHWProgramID) { 157 // detach the current program so there is no confusion on OpenGL's part 158 // that we want it to be deleted 159 SkASSERT(fHWProgramID == fCurrentProgram->programID()); 160 GL_CALL(UseProgram(0)); 161 } 162 163 delete fProgramCache; 164 165 // This must be called by before the GrDrawTarget destructor 166 this->releaseGeometry(); 167 // This subclass must do this before the base class destructor runs 168 // since we will unref the GrGLInterface. 169 this->releaseResources(); 170} 171 172/////////////////////////////////////////////////////////////////////////////// 173 174 175GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig readConfig, 176 GrPixelConfig surfaceConfig) const { 177 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig) { 178 return kBGRA_8888_GrPixelConfig; 179 } else if (this->glContext().isMesa() && 180 GrBytesPerPixel(readConfig) == 4 && 181 GrPixelConfigSwapRAndB(readConfig) == surfaceConfig) { 182 // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa. 183 // Perhaps this should be guarded by some compiletime or runtime check. 184 return surfaceConfig; 185 } else if (readConfig == kBGRA_8888_GrPixelConfig && 186 !this->glCaps().readPixelsSupported(this->glInterface(), 187 GR_GL_BGRA, GR_GL_UNSIGNED_BYTE)) { 188 return kRGBA_8888_GrPixelConfig; 189 } else { 190 return readConfig; 191 } 192} 193 194GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig writeConfig, 195 GrPixelConfig surfaceConfig) const { 196 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == writeConfig) { 197 return kBGRA_8888_GrPixelConfig; 198 } else { 199 return writeConfig; 200 } 201} 202 203bool GrGpuGL::canWriteTexturePixels(const GrTexture* texture, GrPixelConfig srcConfig) const { 204 if (kIndex_8_GrPixelConfig == srcConfig || kIndex_8_GrPixelConfig == texture->config()) { 205 return false; 206 } 207 if (srcConfig != texture->config() && kGLES_GrGLStandard == this->glStandard()) { 208 // In general ES2 requires the internal format of the texture and the format of the src 209 // pixels to match. However, It may or may not be possible to upload BGRA data to a RGBA 210 // texture. It depends upon which extension added BGRA. The Apple extension allows it 211 // (BGRA's internal format is RGBA) while the EXT extension does not (BGRA is its own 212 // internal format). 213 if (this->glCaps().isConfigTexturable(kBGRA_8888_GrPixelConfig) && 214 !this->glCaps().bgraIsInternalFormat() && 215 kBGRA_8888_GrPixelConfig == srcConfig && 216 kRGBA_8888_GrPixelConfig == texture->config()) { 217 return true; 218 } else { 219 return false; 220 } 221 } else { 222 return true; 223 } 224} 225 226bool GrGpuGL::fullReadPixelsIsFasterThanPartial() const { 227 return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL); 228} 229 230void GrGpuGL::onResetContext(uint32_t resetBits) { 231 // we don't use the zb at all 232 if (resetBits & kMisc_GrGLBackendState) { 233 GL_CALL(Disable(GR_GL_DEPTH_TEST)); 234 GL_CALL(DepthMask(GR_GL_FALSE)); 235 236 fHWDrawFace = GrDrawState::kInvalid_DrawFace; 237 fHWDitherEnabled = kUnknown_TriState; 238 239 if (kGL_GrGLStandard == this->glStandard()) { 240 // Desktop-only state that we never change 241 if (!this->glCaps().isCoreProfile()) { 242 GL_CALL(Disable(GR_GL_POINT_SMOOTH)); 243 GL_CALL(Disable(GR_GL_LINE_SMOOTH)); 244 GL_CALL(Disable(GR_GL_POLYGON_SMOOTH)); 245 GL_CALL(Disable(GR_GL_POLYGON_STIPPLE)); 246 GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP)); 247 GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP)); 248 } 249 // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a 250 // core profile. This seems like a bug since the core spec removes any mention of 251 // GL_ARB_imaging. 252 if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) { 253 GL_CALL(Disable(GR_GL_COLOR_TABLE)); 254 } 255 GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL)); 256 // Since ES doesn't support glPointSize at all we always use the VS to 257 // set the point size 258 GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE)); 259 260 // We should set glPolygonMode(FRONT_AND_BACK,FILL) here, too. It isn't 261 // currently part of our gl interface. There are probably others as 262 // well. 263 } 264 fHWWriteToColor = kUnknown_TriState; 265 // we only ever use lines in hairline mode 266 GL_CALL(LineWidth(1)); 267 } 268 269 if (resetBits & kAA_GrGLBackendState) { 270 fHWAAState.invalidate(); 271 } 272 273 fHWActiveTextureUnitIdx = -1; // invalid 274 275 if (resetBits & kTextureBinding_GrGLBackendState) { 276 for (int s = 0; s < fHWBoundTextures.count(); ++s) { 277 fHWBoundTextures[s] = NULL; 278 } 279 } 280 281 if (resetBits & kBlend_GrGLBackendState) { 282 fHWBlendState.invalidate(); 283 } 284 285 if (resetBits & kView_GrGLBackendState) { 286 fHWScissorSettings.invalidate(); 287 fHWViewport.invalidate(); 288 } 289 290 if (resetBits & kStencil_GrGLBackendState) { 291 fHWStencilSettings.invalidate(); 292 fHWStencilTestEnabled = kUnknown_TriState; 293 } 294 295 // Vertex 296 if (resetBits & kVertex_GrGLBackendState) { 297 fHWGeometryState.invalidate(); 298 } 299 300 if (resetBits & kRenderTarget_GrGLBackendState) { 301 fHWBoundRenderTarget = NULL; 302 } 303 304 if (resetBits & kPathRendering_GrGLBackendState) { 305 if (this->caps()->pathRenderingSupport()) { 306 fHWProjectionMatrixState.invalidate(); 307 // we don't use the model view matrix. 308 GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW)); 309 310 for (int i = 0; i < this->glCaps().maxFixedFunctionTextureCoords(); ++i) { 311 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); 312 fHWPathTexGenSettings[i].fMode = GR_GL_NONE; 313 fHWPathTexGenSettings[i].fNumComponents = 0; 314 } 315 fHWActivePathTexGenSets = 0; 316 } 317 fHWPathStencilSettings.invalidate(); 318 } 319 320 // we assume these values 321 if (resetBits & kPixelStore_GrGLBackendState) { 322 if (this->glCaps().unpackRowLengthSupport()) { 323 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 324 } 325 if (this->glCaps().packRowLengthSupport()) { 326 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 327 } 328 if (this->glCaps().unpackFlipYSupport()) { 329 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 330 } 331 if (this->glCaps().packFlipYSupport()) { 332 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE)); 333 } 334 } 335 336 if (resetBits & kProgram_GrGLBackendState) { 337 fHWProgramID = 0; 338 fSharedGLProgramState.invalidate(); 339 } 340} 341 342namespace { 343 344GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin, bool renderTarget) { 345 // By default, GrRenderTargets are GL's normal orientation so that they 346 // can be drawn to by the outside world without the client having 347 // to render upside down. 348 if (kDefault_GrSurfaceOrigin == origin) { 349 return renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin; 350 } else { 351 return origin; 352 } 353} 354 355} 356 357GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) { 358 if (!this->configToGLFormats(desc.fConfig, false, NULL, NULL, NULL)) { 359 return NULL; 360 } 361 362 if (0 == desc.fTextureHandle) { 363 return NULL; 364 } 365 366 int maxSize = this->caps()->maxTextureSize(); 367 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 368 return NULL; 369 } 370 371 GrGLTexture::Desc glTexDesc; 372 // next line relies on GrBackendTextureDesc's flags matching GrTexture's 373 glTexDesc.fFlags = (GrTextureFlags) desc.fFlags; 374 glTexDesc.fWidth = desc.fWidth; 375 glTexDesc.fHeight = desc.fHeight; 376 glTexDesc.fConfig = desc.fConfig; 377 glTexDesc.fSampleCnt = desc.fSampleCnt; 378 glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle); 379 glTexDesc.fIsWrapped = true; 380 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag); 381 // FIXME: this should be calling resolve_origin(), but Chrome code is currently 382 // assuming the old behaviour, which is that backend textures are always 383 // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to: 384 // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); 385 if (kDefault_GrSurfaceOrigin == desc.fOrigin) { 386 glTexDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; 387 } else { 388 glTexDesc.fOrigin = desc.fOrigin; 389 } 390 391 GrGLTexture* texture = NULL; 392 if (renderTarget) { 393 GrGLRenderTarget::Desc glRTDesc; 394 glRTDesc.fRTFBOID = 0; 395 glRTDesc.fTexFBOID = 0; 396 glRTDesc.fMSColorRenderbufferID = 0; 397 glRTDesc.fConfig = desc.fConfig; 398 glRTDesc.fSampleCnt = desc.fSampleCnt; 399 glRTDesc.fOrigin = glTexDesc.fOrigin; 400 glRTDesc.fCheckAllocation = false; 401 if (!this->createRenderTargetObjects(glTexDesc.fWidth, 402 glTexDesc.fHeight, 403 glTexDesc.fTextureID, 404 &glRTDesc)) { 405 return NULL; 406 } 407 texture = SkNEW_ARGS(GrGLTexture, (this, glTexDesc, glRTDesc)); 408 } else { 409 texture = SkNEW_ARGS(GrGLTexture, (this, glTexDesc)); 410 } 411 if (NULL == texture) { 412 return NULL; 413 } 414 415 return texture; 416} 417 418GrRenderTarget* GrGpuGL::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 419 GrGLRenderTarget::Desc glDesc; 420 glDesc.fConfig = desc.fConfig; 421 glDesc.fRTFBOID = static_cast<GrGLuint>(desc.fRenderTargetHandle); 422 glDesc.fMSColorRenderbufferID = 0; 423 glDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 424 glDesc.fSampleCnt = desc.fSampleCnt; 425 glDesc.fIsWrapped = true; 426 glDesc.fCheckAllocation = false; 427 428 glDesc.fOrigin = resolve_origin(desc.fOrigin, true); 429 GrGLIRect viewport; 430 viewport.fLeft = 0; 431 viewport.fBottom = 0; 432 viewport.fWidth = desc.fWidth; 433 viewport.fHeight = desc.fHeight; 434 435 GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget, 436 (this, glDesc, viewport)); 437 if (desc.fStencilBits) { 438 GrGLStencilBuffer::Format format; 439 format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat; 440 format.fPacked = false; 441 format.fStencilBits = desc.fStencilBits; 442 format.fTotalBits = desc.fStencilBits; 443 static const bool kIsSBWrapped = false; 444 GrGLStencilBuffer* sb = SkNEW_ARGS(GrGLStencilBuffer, 445 (this, 446 kIsSBWrapped, 447 0, 448 desc.fWidth, 449 desc.fHeight, 450 desc.fSampleCnt, 451 format)); 452 tgt->setStencilBuffer(sb); 453 sb->unref(); 454 } 455 return tgt; 456} 457 458//////////////////////////////////////////////////////////////////////////////// 459 460bool GrGpuGL::onWriteTexturePixels(GrTexture* texture, 461 int left, int top, int width, int height, 462 GrPixelConfig config, const void* buffer, 463 size_t rowBytes) { 464 if (NULL == buffer) { 465 return false; 466 } 467 GrGLTexture* glTex = static_cast<GrGLTexture*>(texture); 468 469 this->setScratchTextureUnit(); 470 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); 471 GrGLTexture::Desc desc; 472 desc.fFlags = glTex->desc().fFlags; 473 desc.fWidth = glTex->width(); 474 desc.fHeight = glTex->height(); 475 desc.fConfig = glTex->config(); 476 desc.fSampleCnt = glTex->desc().fSampleCnt; 477 desc.fTextureID = glTex->textureID(); 478 desc.fOrigin = glTex->origin(); 479 480 bool success = false; 481 if (GrPixelConfigIsCompressed(desc.fConfig)) { 482 // We check that config == desc.fConfig in GrGpuGL::canWriteTexturePixels() 483 SkASSERT(config == desc.fConfig); 484 success = this->uploadCompressedTexData(desc, buffer, false, 485 left, top, width, height); 486 } else { 487 success = this->uploadTexData(desc, false, 488 left, top, width, height, 489 config, buffer, rowBytes); 490 } 491 492 if (success) { 493 texture->impl()->dirtyMipMaps(true); 494 return true; 495 } 496 497 return false; 498} 499 500namespace { 501bool adjust_pixel_ops_params(int surfaceWidth, 502 int surfaceHeight, 503 size_t bpp, 504 int* left, int* top, int* width, int* height, 505 const void** data, 506 size_t* rowBytes) { 507 if (!*rowBytes) { 508 *rowBytes = *width * bpp; 509 } 510 511 SkIRect subRect = SkIRect::MakeXYWH(*left, *top, *width, *height); 512 SkIRect bounds = SkIRect::MakeWH(surfaceWidth, surfaceHeight); 513 514 if (!subRect.intersect(bounds)) { 515 return false; 516 } 517 *data = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>(*data) + 518 (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp); 519 520 *left = subRect.fLeft; 521 *top = subRect.fTop; 522 *width = subRect.width(); 523 *height = subRect.height(); 524 return true; 525} 526 527GrGLenum check_alloc_error(const GrTextureDesc& desc, const GrGLInterface* interface) { 528 if (SkToBool(desc.fFlags & kCheckAllocation_GrTextureFlagBit)) { 529 return GR_GL_GET_ERROR(interface); 530 } else { 531 return CHECK_ALLOC_ERROR(interface); 532 } 533} 534 535} 536 537bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc, 538 bool isNewTexture, 539 int left, int top, int width, int height, 540 GrPixelConfig dataConfig, 541 const void* data, 542 size_t rowBytes) { 543 SkASSERT(NULL != data || isNewTexture); 544 545 // If we're uploading compressed data then we should be using uploadCompressedTexData 546 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 547 548 size_t bpp = GrBytesPerPixel(dataConfig); 549 if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top, 550 &width, &height, &data, &rowBytes)) { 551 return false; 552 } 553 size_t trimRowBytes = width * bpp; 554 555 // in case we need a temporary, trimmed copy of the src pixels 556 SkAutoSMalloc<128 * 128> tempStorage; 557 558 // paletted textures cannot be partially updated 559 // We currently lazily create MIPMAPs when the we see a draw with 560 // GrTextureParams::kMipMap_FilterMode. Using texture storage requires that the 561 // MIP levels are all created when the texture is created. So for now we don't use 562 // texture storage. 563 bool useTexStorage = false && 564 isNewTexture && 565 kIndex_8_GrPixelConfig != desc.fConfig && 566 this->glCaps().texStorageSupport(); 567 568 if (useTexStorage && kGL_GrGLStandard == this->glStandard()) { 569 // 565 is not a sized internal format on desktop GL. So on desktop with 570 // 565 we always use an unsized internal format to let the system pick 571 // the best sized format to convert the 565 data to. Since TexStorage 572 // only allows sized internal formats we will instead use TexImage2D. 573 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; 574 } 575 576 GrGLenum internalFormat; 577 GrGLenum externalFormat; 578 GrGLenum externalType; 579 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized 580 // format for glTexImage, unlike ES3 and desktop. However, we allow the driver to decide the 581 // size of the internal format whenever possible and so only use a sized internal format when 582 // using texture storage. 583 if (!this->configToGLFormats(dataConfig, useTexStorage, &internalFormat, 584 &externalFormat, &externalType)) { 585 return false; 586 } 587 588 if (!isNewTexture && GR_GL_PALETTE8_RGBA8 == internalFormat) { 589 // paletted textures cannot be updated 590 return false; 591 } 592 593 /* 594 * check whether to allocate a temporary buffer for flipping y or 595 * because our srcData has extra bytes past each row. If so, we need 596 * to trim those off here, since GL ES may not let us specify 597 * GL_UNPACK_ROW_LENGTH. 598 */ 599 bool restoreGLRowLength = false; 600 bool swFlipY = false; 601 bool glFlipY = false; 602 if (NULL != data) { 603 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 604 if (this->glCaps().unpackFlipYSupport()) { 605 glFlipY = true; 606 } else { 607 swFlipY = true; 608 } 609 } 610 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { 611 // can't use this for flipping, only non-neg values allowed. :( 612 if (rowBytes != trimRowBytes) { 613 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); 614 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); 615 restoreGLRowLength = true; 616 } 617 } else { 618 if (trimRowBytes != rowBytes || swFlipY) { 619 // copy data into our new storage, skipping the trailing bytes 620 size_t trimSize = height * trimRowBytes; 621 const char* src = (const char*)data; 622 if (swFlipY) { 623 src += (height - 1) * rowBytes; 624 } 625 char* dst = (char*)tempStorage.reset(trimSize); 626 for (int y = 0; y < height; y++) { 627 memcpy(dst, src, trimRowBytes); 628 if (swFlipY) { 629 src -= rowBytes; 630 } else { 631 src += rowBytes; 632 } 633 dst += trimRowBytes; 634 } 635 // now point data to our copied version 636 data = tempStorage.get(); 637 } 638 } 639 if (glFlipY) { 640 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); 641 } 642 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, static_cast<GrGLint>(bpp))); 643 } 644 bool succeeded = true; 645 if (isNewTexture && 646 0 == left && 0 == top && 647 desc.fWidth == width && desc.fHeight == height) { 648 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 649 if (useTexStorage) { 650 // We never resize or change formats of textures. 651 GL_ALLOC_CALL(this->glInterface(), 652 TexStorage2D(GR_GL_TEXTURE_2D, 653 1, // levels 654 internalFormat, 655 desc.fWidth, desc.fHeight)); 656 } else { 657 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { 658 GrGLsizei imageSize = desc.fWidth * desc.fHeight + 659 kGrColorTableSize; 660 GL_ALLOC_CALL(this->glInterface(), 661 CompressedTexImage2D(GR_GL_TEXTURE_2D, 662 0, // level 663 internalFormat, 664 desc.fWidth, desc.fHeight, 665 0, // border 666 imageSize, 667 data)); 668 } else { 669 GL_ALLOC_CALL(this->glInterface(), 670 TexImage2D(GR_GL_TEXTURE_2D, 671 0, // level 672 internalFormat, 673 desc.fWidth, desc.fHeight, 674 0, // border 675 externalFormat, externalType, 676 data)); 677 } 678 } 679 GrGLenum error = check_alloc_error(desc, this->glInterface()); 680 if (error != GR_GL_NO_ERROR) { 681 succeeded = false; 682 } else { 683 // if we have data and we used TexStorage to create the texture, we 684 // now upload with TexSubImage. 685 if (NULL != data && useTexStorage) { 686 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, 687 0, // level 688 left, top, 689 width, height, 690 externalFormat, externalType, 691 data)); 692 } 693 } 694 } else { 695 if (swFlipY || glFlipY) { 696 top = desc.fHeight - (top + height); 697 } 698 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, 699 0, // level 700 left, top, 701 width, height, 702 externalFormat, externalType, data)); 703 } 704 705 if (restoreGLRowLength) { 706 SkASSERT(this->glCaps().unpackRowLengthSupport()); 707 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 708 } 709 if (glFlipY) { 710 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 711 } 712 return succeeded; 713} 714 715// TODO: This function is using a lot of wonky semantics like, if width == -1 716// then set width = desc.fWdith ... blah. A better way to do it might be to 717// create a CompressedTexData struct that takes a desc/ptr and figures out 718// the proper upload semantics. Then users can construct this function how they 719// see fit if they want to go against the "standard" way to do it. 720bool GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc, 721 const void* data, 722 bool isNewTexture, 723 int left, int top, int width, int height) { 724 SkASSERT(NULL != data || isNewTexture); 725 726 // No support for software flip y, yet... 727 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); 728 729 if (-1 == width) { 730 width = desc.fWidth; 731 } 732#ifdef SK_DEBUG 733 else { 734 SkASSERT(width <= desc.fWidth); 735 } 736#endif 737 738 if (-1 == height) { 739 height = desc.fHeight; 740 } 741#ifdef SK_DEBUG 742 else { 743 SkASSERT(height <= desc.fHeight); 744 } 745#endif 746 747 // Make sure that the width and height that we pass to OpenGL 748 // is a multiple of the block size. 749 int dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height); 750 751 // We only need the internal format for compressed 2D textures. 752 GrGLenum internalFormat = 0; 753 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NULL)) { 754 return false; 755 } 756 757 bool succeeded = true; 758 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 759 760 if (isNewTexture) { 761 GL_ALLOC_CALL(this->glInterface(), 762 CompressedTexImage2D(GR_GL_TEXTURE_2D, 763 0, // level 764 internalFormat, 765 width, height, 766 0, // border 767 dataSize, 768 data)); 769 } else { 770 GL_ALLOC_CALL(this->glInterface(), 771 CompressedTexSubImage2D(GR_GL_TEXTURE_2D, 772 0, // level 773 left, top, 774 width, height, 775 internalFormat, 776 dataSize, 777 data)); 778 } 779 780 GrGLenum error = check_alloc_error(desc, this->glInterface()); 781 if (error != GR_GL_NO_ERROR) { 782 succeeded = false; 783 } 784 return succeeded; 785} 786 787static bool renderbuffer_storage_msaa(GrGLContext& ctx, 788 int sampleCount, 789 GrGLenum format, 790 int width, int height) { 791 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); 792 SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType()); 793 switch (ctx.caps()->msFBOType()) { 794 case GrGLCaps::kDesktop_ARB_MSFBOType: 795 case GrGLCaps::kDesktop_EXT_MSFBOType: 796 case GrGLCaps::kES_3_0_MSFBOType: 797 GL_ALLOC_CALL(ctx.interface(), 798 RenderbufferStorageMultisample(GR_GL_RENDERBUFFER, 799 sampleCount, 800 format, 801 width, height)); 802 break; 803 case GrGLCaps::kES_Apple_MSFBOType: 804 GL_ALLOC_CALL(ctx.interface(), 805 RenderbufferStorageMultisampleES2APPLE(GR_GL_RENDERBUFFER, 806 sampleCount, 807 format, 808 width, height)); 809 break; 810 case GrGLCaps::kES_EXT_MsToTexture_MSFBOType: 811 case GrGLCaps::kES_IMG_MsToTexture_MSFBOType: 812 GL_ALLOC_CALL(ctx.interface(), 813 RenderbufferStorageMultisampleES2EXT(GR_GL_RENDERBUFFER, 814 sampleCount, 815 format, 816 width, height)); 817 break; 818 case GrGLCaps::kNone_MSFBOType: 819 SkFAIL("Shouldn't be here if we don't support multisampled renderbuffers."); 820 break; 821 } 822 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface()));; 823} 824 825bool GrGpuGL::createRenderTargetObjects(int width, int height, 826 GrGLuint texID, 827 GrGLRenderTarget::Desc* desc) { 828 desc->fMSColorRenderbufferID = 0; 829 desc->fRTFBOID = 0; 830 desc->fTexFBOID = 0; 831 desc->fIsWrapped = false; 832 833 GrGLenum status; 834 835 GrGLenum msColorFormat = 0; // suppress warning 836 837 if (desc->fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) { 838 goto FAILED; 839 } 840 841 GL_CALL(GenFramebuffers(1, &desc->fTexFBOID)); 842 if (!desc->fTexFBOID) { 843 goto FAILED; 844 } 845 846 847 // If we are using multisampling we will create two FBOS. We render to one and then resolve to 848 // the texture bound to the other. The exception is the IMG multisample extension. With this 849 // extension the texture is multisampled when rendered to and then auto-resolves it when it is 850 // rendered from. 851 if (desc->fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { 852 GL_CALL(GenFramebuffers(1, &desc->fRTFBOID)); 853 GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID)); 854 if (!desc->fRTFBOID || 855 !desc->fMSColorRenderbufferID || 856 !this->configToGLFormats(desc->fConfig, 857 // ES2 and ES3 require sized internal formats for rb storage. 858 kGLES_GrGLStandard == this->glStandard(), 859 &msColorFormat, 860 NULL, 861 NULL)) { 862 goto FAILED; 863 } 864 } else { 865 desc->fRTFBOID = desc->fTexFBOID; 866 } 867 868 // below here we may bind the FBO 869 fHWBoundRenderTarget = NULL; 870 if (desc->fRTFBOID != desc->fTexFBOID) { 871 SkASSERT(desc->fSampleCnt > 0); 872 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, 873 desc->fMSColorRenderbufferID)); 874 if (!renderbuffer_storage_msaa(fGLContext, 875 desc->fSampleCnt, 876 msColorFormat, 877 width, height)) { 878 goto FAILED; 879 } 880 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fRTFBOID)); 881 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 882 GR_GL_COLOR_ATTACHMENT0, 883 GR_GL_RENDERBUFFER, 884 desc->fMSColorRenderbufferID)); 885 if (desc->fCheckAllocation || 886 !this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) { 887 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 888 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 889 goto FAILED; 890 } 891 fGLContext.caps()->markConfigAsValidColorAttachment(desc->fConfig); 892 } 893 } 894 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID)); 895 896 if (this->glCaps().usesImplicitMSAAResolve() && desc->fSampleCnt > 0) { 897 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, 898 GR_GL_COLOR_ATTACHMENT0, 899 GR_GL_TEXTURE_2D, 900 texID, 0, desc->fSampleCnt)); 901 } else { 902 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, 903 GR_GL_COLOR_ATTACHMENT0, 904 GR_GL_TEXTURE_2D, 905 texID, 0)); 906 } 907 if (desc->fCheckAllocation || 908 !this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) { 909 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 910 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 911 goto FAILED; 912 } 913 fGLContext.caps()->markConfigAsValidColorAttachment(desc->fConfig); 914 } 915 916 return true; 917 918FAILED: 919 if (desc->fMSColorRenderbufferID) { 920 GL_CALL(DeleteRenderbuffers(1, &desc->fMSColorRenderbufferID)); 921 } 922 if (desc->fRTFBOID != desc->fTexFBOID) { 923 GL_CALL(DeleteFramebuffers(1, &desc->fRTFBOID)); 924 } 925 if (desc->fTexFBOID) { 926 GL_CALL(DeleteFramebuffers(1, &desc->fTexFBOID)); 927 } 928 return false; 929} 930 931// good to set a break-point here to know when createTexture fails 932static GrTexture* return_null_texture() { 933// SkDEBUGFAIL("null texture"); 934 return NULL; 935} 936 937#if 0 && defined(SK_DEBUG) 938static size_t as_size_t(int x) { 939 return x; 940} 941#endif 942 943GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc, 944 const void* srcData, 945 size_t rowBytes) { 946 947 GrGLTexture::Desc glTexDesc; 948 GrGLRenderTarget::Desc glRTDesc; 949 950 // Attempt to catch un- or wrongly initialized sample counts; 951 SkASSERT(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64); 952 // We fail if the MSAA was requested and is not available. 953 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) { 954 //GrPrintf("MSAA RT requested but not supported on this platform."); 955 return return_null_texture(); 956 } 957 // If the sample count exceeds the max then we clamp it. 958 glTexDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()); 959 960 glTexDesc.fFlags = desc.fFlags; 961 glTexDesc.fWidth = desc.fWidth; 962 glTexDesc.fHeight = desc.fHeight; 963 glTexDesc.fConfig = desc.fConfig; 964 glTexDesc.fIsWrapped = false; 965 966 glRTDesc.fMSColorRenderbufferID = 0; 967 glRTDesc.fRTFBOID = 0; 968 glRTDesc.fTexFBOID = 0; 969 glRTDesc.fIsWrapped = false; 970 glRTDesc.fConfig = glTexDesc.fConfig; 971 glRTDesc.fCheckAllocation = SkToBool(desc.fFlags & kCheckAllocation_GrTextureFlagBit); 972 973 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrTextureFlagBit); 974 975 glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); 976 glRTDesc.fOrigin = glTexDesc.fOrigin; 977 978 glRTDesc.fSampleCnt = glTexDesc.fSampleCnt; 979 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && 980 desc.fSampleCnt) { 981 //GrPrintf("MSAA RT requested but not supported on this platform."); 982 return return_null_texture(); 983 } 984 985 if (renderTarget) { 986 int maxRTSize = this->caps()->maxRenderTargetSize(); 987 if (glTexDesc.fWidth > maxRTSize || glTexDesc.fHeight > maxRTSize) { 988 return return_null_texture(); 989 } 990 } else { 991 int maxSize = this->caps()->maxTextureSize(); 992 if (glTexDesc.fWidth > maxSize || glTexDesc.fHeight > maxSize) { 993 return return_null_texture(); 994 } 995 } 996 997 GL_CALL(GenTextures(1, &glTexDesc.fTextureID)); 998 999 if (!glTexDesc.fTextureID) { 1000 return return_null_texture(); 1001 } 1002 1003 this->setScratchTextureUnit(); 1004 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID)); 1005 1006 if (renderTarget && this->glCaps().textureUsageSupport()) { 1007 // provides a hint about how this texture will be used 1008 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1009 GR_GL_TEXTURE_USAGE, 1010 GR_GL_FRAMEBUFFER_ATTACHMENT)); 1011 } 1012 1013 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1014 // drivers have a bug where an FBO won't be complete if it includes a 1015 // texture that is not mipmap complete (considering the filter in use). 1016 GrGLTexture::TexParams initialTexParams; 1017 // we only set a subset here so invalidate first 1018 initialTexParams.invalidate(); 1019 initialTexParams.fMinFilter = GR_GL_NEAREST; 1020 initialTexParams.fMagFilter = GR_GL_NEAREST; 1021 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; 1022 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; 1023 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1024 GR_GL_TEXTURE_MAG_FILTER, 1025 initialTexParams.fMagFilter)); 1026 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1027 GR_GL_TEXTURE_MIN_FILTER, 1028 initialTexParams.fMinFilter)); 1029 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1030 GR_GL_TEXTURE_WRAP_S, 1031 initialTexParams.fWrapS)); 1032 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1033 GR_GL_TEXTURE_WRAP_T, 1034 initialTexParams.fWrapT)); 1035 if (!this->uploadTexData(glTexDesc, true, 0, 0, 1036 glTexDesc.fWidth, glTexDesc.fHeight, 1037 desc.fConfig, srcData, rowBytes)) { 1038 GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID)); 1039 return return_null_texture(); 1040 } 1041 1042 GrGLTexture* tex; 1043 if (renderTarget) { 1044 // unbind the texture from the texture unit before binding it to the frame buffer 1045 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); 1046 1047 if (!this->createRenderTargetObjects(glTexDesc.fWidth, 1048 glTexDesc.fHeight, 1049 glTexDesc.fTextureID, 1050 &glRTDesc)) { 1051 GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID)); 1052 return return_null_texture(); 1053 } 1054 tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc, glRTDesc)); 1055 } else { 1056 tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc)); 1057 } 1058 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1059#ifdef TRACE_TEXTURE_CREATION 1060 GrPrintf("--- new texture [%d] size=(%d %d) config=%d\n", 1061 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1062#endif 1063 return tex; 1064} 1065 1066GrTexture* GrGpuGL::onCreateCompressedTexture(const GrTextureDesc& desc, 1067 const void* srcData) { 1068 1069 if(SkToBool(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { 1070 return return_null_texture(); 1071 } 1072 1073 // Make sure that we're not flipping Y. 1074 GrSurfaceOrigin texOrigin = resolve_origin(desc.fOrigin, false); 1075 if (kBottomLeft_GrSurfaceOrigin == texOrigin) { 1076 return return_null_texture(); 1077 } 1078 1079 GrGLTexture::Desc glTexDesc; 1080 1081 glTexDesc.fFlags = desc.fFlags; 1082 glTexDesc.fWidth = desc.fWidth; 1083 glTexDesc.fHeight = desc.fHeight; 1084 glTexDesc.fConfig = desc.fConfig; 1085 glTexDesc.fIsWrapped = false; 1086 glTexDesc.fOrigin = texOrigin; 1087 1088 int maxSize = this->caps()->maxTextureSize(); 1089 if (glTexDesc.fWidth > maxSize || glTexDesc.fHeight > maxSize) { 1090 return return_null_texture(); 1091 } 1092 1093 GL_CALL(GenTextures(1, &glTexDesc.fTextureID)); 1094 1095 if (!glTexDesc.fTextureID) { 1096 return return_null_texture(); 1097 } 1098 1099 this->setScratchTextureUnit(); 1100 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID)); 1101 1102 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1103 // drivers have a bug where an FBO won't be complete if it includes a 1104 // texture that is not mipmap complete (considering the filter in use). 1105 GrGLTexture::TexParams initialTexParams; 1106 // we only set a subset here so invalidate first 1107 initialTexParams.invalidate(); 1108 initialTexParams.fMinFilter = GR_GL_NEAREST; 1109 initialTexParams.fMagFilter = GR_GL_NEAREST; 1110 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; 1111 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; 1112 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1113 GR_GL_TEXTURE_MAG_FILTER, 1114 initialTexParams.fMagFilter)); 1115 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1116 GR_GL_TEXTURE_MIN_FILTER, 1117 initialTexParams.fMinFilter)); 1118 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1119 GR_GL_TEXTURE_WRAP_S, 1120 initialTexParams.fWrapS)); 1121 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1122 GR_GL_TEXTURE_WRAP_T, 1123 initialTexParams.fWrapT)); 1124 1125 if (!this->uploadCompressedTexData(glTexDesc, srcData)) { 1126 GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID)); 1127 return return_null_texture(); 1128 } 1129 1130 GrGLTexture* tex; 1131 tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc)); 1132 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1133#ifdef TRACE_TEXTURE_CREATION 1134 GrPrintf("--- new compressed texture [%d] size=(%d %d) config=%d\n", 1135 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1136#endif 1137 return tex; 1138} 1139 1140namespace { 1141 1142const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount; 1143 1144void inline get_stencil_rb_sizes(const GrGLInterface* gl, 1145 GrGLStencilBuffer::Format* format) { 1146 1147 // we shouldn't ever know one size and not the other 1148 SkASSERT((kUnknownBitCount == format->fStencilBits) == 1149 (kUnknownBitCount == format->fTotalBits)); 1150 if (kUnknownBitCount == format->fStencilBits) { 1151 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 1152 GR_GL_RENDERBUFFER_STENCIL_SIZE, 1153 (GrGLint*)&format->fStencilBits); 1154 if (format->fPacked) { 1155 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 1156 GR_GL_RENDERBUFFER_DEPTH_SIZE, 1157 (GrGLint*)&format->fTotalBits); 1158 format->fTotalBits += format->fStencilBits; 1159 } else { 1160 format->fTotalBits = format->fStencilBits; 1161 } 1162 } 1163} 1164} 1165 1166bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, 1167 int width, int height) { 1168 1169 // All internally created RTs are also textures. We don't create 1170 // SBs for a client's standalone RT (that is a RT that isn't also a texture). 1171 SkASSERT(rt->asTexture()); 1172 SkASSERT(width >= rt->width()); 1173 SkASSERT(height >= rt->height()); 1174 1175 int samples = rt->numSamples(); 1176 GrGLuint sbID; 1177 GL_CALL(GenRenderbuffers(1, &sbID)); 1178 if (!sbID) { 1179 return false; 1180 } 1181 1182 int stencilFmtCnt = this->glCaps().stencilFormats().count(); 1183 for (int i = 0; i < stencilFmtCnt; ++i) { 1184 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID)); 1185 // we start with the last stencil format that succeeded in hopes 1186 // that we won't go through this loop more than once after the 1187 // first (painful) stencil creation. 1188 int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt; 1189 const GrGLCaps::StencilFormat& sFmt = 1190 this->glCaps().stencilFormats()[sIdx]; 1191 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1192 // we do this "if" so that we don't call the multisample 1193 // version on a GL that doesn't have an MSAA extension. 1194 bool created; 1195 if (samples > 0) { 1196 created = renderbuffer_storage_msaa(fGLContext, 1197 samples, 1198 sFmt.fInternalFormat, 1199 width, height); 1200 } else { 1201 GL_ALLOC_CALL(this->glInterface(), 1202 RenderbufferStorage(GR_GL_RENDERBUFFER, 1203 sFmt.fInternalFormat, 1204 width, height)); 1205 created = 1206 (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface())); 1207 } 1208 if (created) { 1209 // After sized formats we attempt an unsized format and take 1210 // whatever sizes GL gives us. In that case we query for the size. 1211 GrGLStencilBuffer::Format format = sFmt; 1212 get_stencil_rb_sizes(this->glInterface(), &format); 1213 static const bool kIsWrapped = false; 1214 SkAutoTUnref<GrStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, 1215 (this, kIsWrapped, sbID, width, height, 1216 samples, format))); 1217 if (this->attachStencilBufferToRenderTarget(sb, rt)) { 1218 fLastSuccessfulStencilFmtIdx = sIdx; 1219 sb->transferToCache(); 1220 rt->setStencilBuffer(sb); 1221 return true; 1222 } 1223 sb->abandon(); // otherwise we lose sbID 1224 } 1225 } 1226 GL_CALL(DeleteRenderbuffers(1, &sbID)); 1227 return false; 1228} 1229 1230bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTarget* rt) { 1231 GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt; 1232 1233 GrGLuint fbo = glrt->renderFBOID(); 1234 1235 if (NULL == sb) { 1236 if (NULL != rt->getStencilBuffer()) { 1237 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1238 GR_GL_STENCIL_ATTACHMENT, 1239 GR_GL_RENDERBUFFER, 0)); 1240 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1241 GR_GL_DEPTH_ATTACHMENT, 1242 GR_GL_RENDERBUFFER, 0)); 1243#ifdef SK_DEBUG 1244 GrGLenum status; 1245 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1246 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); 1247#endif 1248 } 1249 return true; 1250 } else { 1251 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); 1252 GrGLuint rb = glsb->renderbufferID(); 1253 1254 fHWBoundRenderTarget = NULL; 1255 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); 1256 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1257 GR_GL_STENCIL_ATTACHMENT, 1258 GR_GL_RENDERBUFFER, rb)); 1259 if (glsb->format().fPacked) { 1260 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1261 GR_GL_DEPTH_ATTACHMENT, 1262 GR_GL_RENDERBUFFER, rb)); 1263 } else { 1264 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1265 GR_GL_DEPTH_ATTACHMENT, 1266 GR_GL_RENDERBUFFER, 0)); 1267 } 1268 1269 GrGLenum status; 1270 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(), glsb->format())) { 1271 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1272 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1273 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1274 GR_GL_STENCIL_ATTACHMENT, 1275 GR_GL_RENDERBUFFER, 0)); 1276 if (glsb->format().fPacked) { 1277 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1278 GR_GL_DEPTH_ATTACHMENT, 1279 GR_GL_RENDERBUFFER, 0)); 1280 } 1281 return false; 1282 } else { 1283 fGLContext.caps()->markColorConfigAndStencilFormatAsVerified( 1284 rt->config(), 1285 glsb->format()); 1286 } 1287 } 1288 return true; 1289 } 1290} 1291 1292//////////////////////////////////////////////////////////////////////////////// 1293 1294GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(size_t size, bool dynamic) { 1295 GrGLVertexBuffer::Desc desc; 1296 desc.fDynamic = dynamic; 1297 desc.fSizeInBytes = size; 1298 desc.fIsWrapped = false; 1299 1300 if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) { 1301 desc.fID = 0; 1302 GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc)); 1303 return vertexBuffer; 1304 } else { 1305 GL_CALL(GenBuffers(1, &desc.fID)); 1306 if (desc.fID) { 1307 fHWGeometryState.setVertexBufferID(this, desc.fID); 1308 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1309 // make sure driver can allocate memory for this buffer 1310 GL_ALLOC_CALL(this->glInterface(), 1311 BufferData(GR_GL_ARRAY_BUFFER, 1312 (GrGLsizeiptr) desc.fSizeInBytes, 1313 NULL, // data ptr 1314 desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW)); 1315 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) { 1316 GL_CALL(DeleteBuffers(1, &desc.fID)); 1317 this->notifyVertexBufferDelete(desc.fID); 1318 return NULL; 1319 } 1320 GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc)); 1321 return vertexBuffer; 1322 } 1323 return NULL; 1324 } 1325} 1326 1327GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(size_t size, bool dynamic) { 1328 GrGLIndexBuffer::Desc desc; 1329 desc.fDynamic = dynamic; 1330 desc.fSizeInBytes = size; 1331 desc.fIsWrapped = false; 1332 1333 if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) { 1334 desc.fID = 0; 1335 GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc)); 1336 return indexBuffer; 1337 } else { 1338 GL_CALL(GenBuffers(1, &desc.fID)); 1339 if (desc.fID) { 1340 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, desc.fID); 1341 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1342 // make sure driver can allocate memory for this buffer 1343 GL_ALLOC_CALL(this->glInterface(), 1344 BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, 1345 (GrGLsizeiptr) desc.fSizeInBytes, 1346 NULL, // data ptr 1347 desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW)); 1348 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) { 1349 GL_CALL(DeleteBuffers(1, &desc.fID)); 1350 this->notifyIndexBufferDelete(desc.fID); 1351 return NULL; 1352 } 1353 GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc)); 1354 return indexBuffer; 1355 } 1356 return NULL; 1357 } 1358} 1359 1360GrPath* GrGpuGL::onCreatePath(const SkPath& inPath, const SkStrokeRec& stroke) { 1361 SkASSERT(this->caps()->pathRenderingSupport()); 1362 return SkNEW_ARGS(GrGLPath, (this, inPath, stroke)); 1363} 1364 1365void GrGpuGL::flushScissor() { 1366 if (fScissorState.fEnabled) { 1367 // Only access the RT if scissoring is being enabled. We can call this before performing 1368 // a glBitframebuffer for a surface->surface copy, which requires no RT to be bound to the 1369 // GrDrawState. 1370 const GrDrawState& drawState = this->getDrawState(); 1371 const GrGLRenderTarget* rt = 1372 static_cast<const GrGLRenderTarget*>(drawState.getRenderTarget()); 1373 1374 SkASSERT(NULL != rt); 1375 const GrGLIRect& vp = rt->getViewport(); 1376 GrGLIRect scissor; 1377 scissor.setRelativeTo(vp, 1378 fScissorState.fRect.fLeft, 1379 fScissorState.fRect.fTop, 1380 fScissorState.fRect.width(), 1381 fScissorState.fRect.height(), 1382 rt->origin()); 1383 // if the scissor fully contains the viewport then we fall through and 1384 // disable the scissor test. 1385 if (!scissor.contains(vp)) { 1386 if (fHWScissorSettings.fRect != scissor) { 1387 scissor.pushToGLScissor(this->glInterface()); 1388 fHWScissorSettings.fRect = scissor; 1389 } 1390 if (kYes_TriState != fHWScissorSettings.fEnabled) { 1391 GL_CALL(Enable(GR_GL_SCISSOR_TEST)); 1392 fHWScissorSettings.fEnabled = kYes_TriState; 1393 } 1394 return; 1395 } 1396 } 1397 if (kNo_TriState != fHWScissorSettings.fEnabled) { 1398 GL_CALL(Disable(GR_GL_SCISSOR_TEST)); 1399 fHWScissorSettings.fEnabled = kNo_TriState; 1400 return; 1401 } 1402} 1403 1404void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) { 1405 const GrDrawState& drawState = this->getDrawState(); 1406 const GrRenderTarget* rt = drawState.getRenderTarget(); 1407 // parent class should never let us get here with no RT 1408 SkASSERT(NULL != rt); 1409 1410 if (canIgnoreRect && this->glCaps().fullClearIsFree()) { 1411 rect = NULL; 1412 } 1413 1414 SkIRect clippedRect; 1415 if (NULL != rect) { 1416 // flushScissor expects rect to be clipped to the target. 1417 clippedRect = *rect; 1418 SkIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height()); 1419 if (clippedRect.intersect(rtRect)) { 1420 rect = &clippedRect; 1421 } else { 1422 return; 1423 } 1424 } 1425 1426 this->flushRenderTarget(rect); 1427 GrAutoTRestore<ScissorState> asr(&fScissorState); 1428 fScissorState.fEnabled = (NULL != rect); 1429 if (fScissorState.fEnabled) { 1430 fScissorState.fRect = *rect; 1431 } 1432 this->flushScissor(); 1433 1434 GrGLfloat r, g, b, a; 1435 static const GrGLfloat scale255 = 1.f / 255.f; 1436 a = GrColorUnpackA(color) * scale255; 1437 GrGLfloat scaleRGB = scale255; 1438 r = GrColorUnpackR(color) * scaleRGB; 1439 g = GrColorUnpackG(color) * scaleRGB; 1440 b = GrColorUnpackB(color) * scaleRGB; 1441 1442 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 1443 fHWWriteToColor = kYes_TriState; 1444 GL_CALL(ClearColor(r, g, b, a)); 1445 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); 1446} 1447 1448void GrGpuGL::discard(GrRenderTarget* renderTarget) { 1449 if (!this->caps()->discardRenderTargetSupport()) { 1450 return; 1451 } 1452 if (NULL == renderTarget) { 1453 renderTarget = this->drawState()->getRenderTarget(); 1454 if (NULL == renderTarget) { 1455 return; 1456 } 1457 } 1458 1459 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); 1460 if (renderTarget != fHWBoundRenderTarget) { 1461 fHWBoundRenderTarget = NULL; 1462 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID())); 1463 } 1464 switch (this->glCaps().invalidateFBType()) { 1465 case GrGLCaps::kNone_FBFetchType: 1466 SkFAIL("Should never get here."); 1467 break; 1468 case GrGLCaps::kInvalidate_InvalidateFBType: 1469 if (0 == glRT->renderFBOID()) { 1470 // When rendering to the default framebuffer the legal values for attachments 1471 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the various FBO attachment 1472 // types. 1473 static const GrGLenum attachments[] = { GR_GL_COLOR }; 1474 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments), 1475 attachments)); 1476 } else { 1477 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0 }; 1478 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments), 1479 attachments)); 1480 } 1481 break; 1482 case GrGLCaps::kDiscard_InvalidateFBType: { 1483 if (0 == glRT->renderFBOID()) { 1484 // When rendering to the default framebuffer the legal values for attachments 1485 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the various FBO attachment 1486 // types. See glDiscardFramebuffer() spec. 1487 static const GrGLenum attachments[] = { GR_GL_COLOR }; 1488 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments), 1489 attachments)); 1490 } else { 1491 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0 }; 1492 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments), 1493 attachments)); 1494 } 1495 break; 1496 } 1497 } 1498 renderTarget->flagAsResolved(); 1499} 1500 1501 1502void GrGpuGL::clearStencil() { 1503 if (NULL == this->getDrawState().getRenderTarget()) { 1504 return; 1505 } 1506 1507 this->flushRenderTarget(&SkIRect::EmptyIRect()); 1508 1509 GrAutoTRestore<ScissorState> asr(&fScissorState); 1510 fScissorState.fEnabled = false; 1511 this->flushScissor(); 1512 1513 GL_CALL(StencilMask(0xffffffff)); 1514 GL_CALL(ClearStencil(0)); 1515 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 1516 fHWStencilSettings.invalidate(); 1517} 1518 1519void GrGpuGL::clearStencilClip(const SkIRect& rect, bool insideClip) { 1520 const GrDrawState& drawState = this->getDrawState(); 1521 const GrRenderTarget* rt = drawState.getRenderTarget(); 1522 SkASSERT(NULL != rt); 1523 1524 // this should only be called internally when we know we have a 1525 // stencil buffer. 1526 SkASSERT(NULL != rt->getStencilBuffer()); 1527 GrGLint stencilBitCount = rt->getStencilBuffer()->bits(); 1528#if 0 1529 SkASSERT(stencilBitCount > 0); 1530 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); 1531#else 1532 // we could just clear the clip bit but when we go through 1533 // ANGLE a partial stencil mask will cause clears to be 1534 // turned into draws. Our contract on GrDrawTarget says that 1535 // changing the clip between stencil passes may or may not 1536 // zero the client's clip bits. So we just clear the whole thing. 1537 static const GrGLint clipStencilMask = ~0; 1538#endif 1539 GrGLint value; 1540 if (insideClip) { 1541 value = (1 << (stencilBitCount - 1)); 1542 } else { 1543 value = 0; 1544 } 1545 this->flushRenderTarget(&SkIRect::EmptyIRect()); 1546 1547 GrAutoTRestore<ScissorState> asr(&fScissorState); 1548 fScissorState.fEnabled = true; 1549 fScissorState.fRect = rect; 1550 this->flushScissor(); 1551 1552 GL_CALL(StencilMask((uint32_t) clipStencilMask)); 1553 GL_CALL(ClearStencil(value)); 1554 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 1555 fHWStencilSettings.invalidate(); 1556} 1557 1558bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget, 1559 int left, int top, 1560 int width, int height, 1561 GrPixelConfig config, 1562 size_t rowBytes) const { 1563 // If this rendertarget is aready TopLeft, we don't need to flip. 1564 if (kTopLeft_GrSurfaceOrigin == renderTarget->origin()) { 1565 return false; 1566 } 1567 1568 // if GL can do the flip then we'll never pay for it. 1569 if (this->glCaps().packFlipYSupport()) { 1570 return false; 1571 } 1572 1573 // If we have to do memcpy to handle non-trim rowBytes then we 1574 // get the flip for free. Otherwise it costs. 1575 if (this->glCaps().packRowLengthSupport()) { 1576 return true; 1577 } 1578 // If we have to do memcpys to handle rowBytes then y-flip is free 1579 // Note the rowBytes might be tight to the passed in data, but if data 1580 // gets clipped in x to the target the rowBytes will no longer be tight. 1581 if (left >= 0 && (left + width) < renderTarget->width()) { 1582 return 0 == rowBytes || 1583 GrBytesPerPixel(config) * width == rowBytes; 1584 } else { 1585 return false; 1586 } 1587} 1588 1589bool GrGpuGL::onReadPixels(GrRenderTarget* target, 1590 int left, int top, 1591 int width, int height, 1592 GrPixelConfig config, 1593 void* buffer, 1594 size_t rowBytes) { 1595 // We cannot read pixels into a compressed buffer 1596 if (GrPixelConfigIsCompressed(config)) { 1597 return false; 1598 } 1599 1600 GrGLenum format = 0; 1601 GrGLenum type = 0; 1602 bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin(); 1603 if (!this->configToGLFormats(config, false, NULL, &format, &type)) { 1604 return false; 1605 } 1606 size_t bpp = GrBytesPerPixel(config); 1607 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, 1608 &left, &top, &width, &height, 1609 const_cast<const void**>(&buffer), 1610 &rowBytes)) { 1611 return false; 1612 } 1613 1614 // resolve the render target if necessary 1615 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); 1616 GrDrawState::AutoRenderTargetRestore artr; 1617 switch (tgt->getResolveType()) { 1618 case GrGLRenderTarget::kCantResolve_ResolveType: 1619 return false; 1620 case GrGLRenderTarget::kAutoResolves_ResolveType: 1621 artr.set(this->drawState(), target); 1622 this->flushRenderTarget(&SkIRect::EmptyIRect()); 1623 break; 1624 case GrGLRenderTarget::kCanResolve_ResolveType: 1625 this->onResolveRenderTarget(tgt); 1626 // we don't track the state of the READ FBO ID. 1627 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, 1628 tgt->textureFBOID())); 1629 break; 1630 default: 1631 SkFAIL("Unknown resolve type"); 1632 } 1633 1634 const GrGLIRect& glvp = tgt->getViewport(); 1635 1636 // the read rect is viewport-relative 1637 GrGLIRect readRect; 1638 readRect.setRelativeTo(glvp, left, top, width, height, target->origin()); 1639 1640 size_t tightRowBytes = bpp * width; 1641 if (0 == rowBytes) { 1642 rowBytes = tightRowBytes; 1643 } 1644 size_t readDstRowBytes = tightRowBytes; 1645 void* readDst = buffer; 1646 1647 // determine if GL can read using the passed rowBytes or if we need 1648 // a scratch buffer. 1649 SkAutoSMalloc<32 * sizeof(GrColor)> scratch; 1650 if (rowBytes != tightRowBytes) { 1651 if (this->glCaps().packRowLengthSupport()) { 1652 SkASSERT(!(rowBytes % sizeof(GrColor))); 1653 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 1654 static_cast<GrGLint>(rowBytes / sizeof(GrColor)))); 1655 readDstRowBytes = rowBytes; 1656 } else { 1657 scratch.reset(tightRowBytes * height); 1658 readDst = scratch.get(); 1659 } 1660 } 1661 if (flipY && this->glCaps().packFlipYSupport()) { 1662 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1)); 1663 } 1664 GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom, 1665 readRect.fWidth, readRect.fHeight, 1666 format, type, readDst)); 1667 if (readDstRowBytes != tightRowBytes) { 1668 SkASSERT(this->glCaps().packRowLengthSupport()); 1669 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 1670 } 1671 if (flipY && this->glCaps().packFlipYSupport()) { 1672 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0)); 1673 flipY = false; 1674 } 1675 1676 // now reverse the order of the rows, since GL's are bottom-to-top, but our 1677 // API presents top-to-bottom. We must preserve the padding contents. Note 1678 // that the above readPixels did not overwrite the padding. 1679 if (readDst == buffer) { 1680 SkASSERT(rowBytes == readDstRowBytes); 1681 if (flipY) { 1682 scratch.reset(tightRowBytes); 1683 void* tmpRow = scratch.get(); 1684 // flip y in-place by rows 1685 const int halfY = height >> 1; 1686 char* top = reinterpret_cast<char*>(buffer); 1687 char* bottom = top + (height - 1) * rowBytes; 1688 for (int y = 0; y < halfY; y++) { 1689 memcpy(tmpRow, top, tightRowBytes); 1690 memcpy(top, bottom, tightRowBytes); 1691 memcpy(bottom, tmpRow, tightRowBytes); 1692 top += rowBytes; 1693 bottom -= rowBytes; 1694 } 1695 } 1696 } else { 1697 SkASSERT(readDst != buffer); SkASSERT(rowBytes != tightRowBytes); 1698 // copy from readDst to buffer while flipping y 1699 // const int halfY = height >> 1; 1700 const char* src = reinterpret_cast<const char*>(readDst); 1701 char* dst = reinterpret_cast<char*>(buffer); 1702 if (flipY) { 1703 dst += (height-1) * rowBytes; 1704 } 1705 for (int y = 0; y < height; y++) { 1706 memcpy(dst, src, tightRowBytes); 1707 src += readDstRowBytes; 1708 if (!flipY) { 1709 dst += rowBytes; 1710 } else { 1711 dst -= rowBytes; 1712 } 1713 } 1714 } 1715 return true; 1716} 1717 1718void GrGpuGL::flushRenderTarget(const SkIRect* bound) { 1719 1720 GrGLRenderTarget* rt = 1721 static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget()); 1722 SkASSERT(NULL != rt); 1723 1724 if (fHWBoundRenderTarget != rt) { 1725 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID())); 1726#ifdef SK_DEBUG 1727 // don't do this check in Chromium -- this is causing 1728 // lots of repeated command buffer flushes when the compositor is 1729 // rendering with Ganesh, which is really slow; even too slow for 1730 // Debug mode. 1731 if (!this->glContext().isChromium()) { 1732 GrGLenum status; 1733 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1734 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1735 GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status); 1736 } 1737 } 1738#endif 1739 fHWBoundRenderTarget = rt; 1740 const GrGLIRect& vp = rt->getViewport(); 1741 if (fHWViewport != vp) { 1742 vp.pushToGLViewport(this->glInterface()); 1743 fHWViewport = vp; 1744 } 1745 } 1746 if (NULL == bound || !bound->isEmpty()) { 1747 rt->flagAsNeedingResolve(bound); 1748 } 1749 1750 GrTexture *texture = rt->asTexture(); 1751 if (NULL != texture) { 1752 texture->impl()->dirtyMipMaps(true); 1753 } 1754} 1755 1756GrGLenum gPrimitiveType2GLMode[] = { 1757 GR_GL_TRIANGLES, 1758 GR_GL_TRIANGLE_STRIP, 1759 GR_GL_TRIANGLE_FAN, 1760 GR_GL_POINTS, 1761 GR_GL_LINES, 1762 GR_GL_LINE_STRIP 1763}; 1764 1765#define SWAP_PER_DRAW 0 1766 1767#if SWAP_PER_DRAW 1768 #if defined(SK_BUILD_FOR_MAC) 1769 #include <AGL/agl.h> 1770 #elif defined(SK_BUILD_FOR_WIN32) 1771 #include <gl/GL.h> 1772 void SwapBuf() { 1773 DWORD procID = GetCurrentProcessId(); 1774 HWND hwnd = GetTopWindow(GetDesktopWindow()); 1775 while(hwnd) { 1776 DWORD wndProcID = 0; 1777 GetWindowThreadProcessId(hwnd, &wndProcID); 1778 if(wndProcID == procID) { 1779 SwapBuffers(GetDC(hwnd)); 1780 } 1781 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); 1782 } 1783 } 1784 #endif 1785#endif 1786 1787void GrGpuGL::onGpuDraw(const DrawInfo& info) { 1788 size_t indexOffsetInBytes; 1789 this->setupGeometry(info, &indexOffsetInBytes); 1790 1791 SkASSERT((size_t)info.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode)); 1792 1793 if (info.isIndexed()) { 1794 GrGLvoid* indices = 1795 reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) * info.startIndex()); 1796 // info.startVertex() was accounted for by setupGeometry. 1797 GL_CALL(DrawElements(gPrimitiveType2GLMode[info.primitiveType()], 1798 info.indexCount(), 1799 GR_GL_UNSIGNED_SHORT, 1800 indices)); 1801 } else { 1802 // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for 1803 // startVertex in the DrawElements case. So we always rely on setupGeometry to have 1804 // accounted for startVertex. 1805 GL_CALL(DrawArrays(gPrimitiveType2GLMode[info.primitiveType()], 0, info.vertexCount())); 1806 } 1807#if SWAP_PER_DRAW 1808 glFlush(); 1809 #if defined(SK_BUILD_FOR_MAC) 1810 aglSwapBuffers(aglGetCurrentContext()); 1811 int set_a_break_pt_here = 9; 1812 aglSwapBuffers(aglGetCurrentContext()); 1813 #elif defined(SK_BUILD_FOR_WIN32) 1814 SwapBuf(); 1815 int set_a_break_pt_here = 9; 1816 SwapBuf(); 1817 #endif 1818#endif 1819} 1820 1821static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) { 1822 switch (op) { 1823 default: 1824 SkFAIL("Unexpected path fill."); 1825 /* fallthrough */; 1826 case kIncClamp_StencilOp: 1827 return GR_GL_COUNT_UP; 1828 case kInvert_StencilOp: 1829 return GR_GL_INVERT; 1830 } 1831} 1832 1833void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { 1834 SkASSERT(this->caps()->pathRenderingSupport()); 1835 1836 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 1837 SkASSERT(NULL != this->drawState()->getRenderTarget()); 1838 SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer()); 1839 1840 flushPathStencilSettings(fill); 1841 1842 // Decide how to manipulate the stencil buffer based on the fill rule. 1843 SkASSERT(!fHWPathStencilSettings.isTwoSided()); 1844 1845 GrGLenum fillMode = 1846 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 1847 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 1848 GL_CALL(StencilFillPath(id, fillMode, writeMask)); 1849} 1850 1851void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) { 1852 SkASSERT(this->caps()->pathRenderingSupport()); 1853 1854 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 1855 SkASSERT(NULL != this->drawState()->getRenderTarget()); 1856 SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer()); 1857 SkASSERT(!fCurrentProgram->hasVertexShader()); 1858 1859 flushPathStencilSettings(fill); 1860 const SkStrokeRec& stroke = path->getStroke(); 1861 1862 SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill); 1863 SkASSERT(!fHWPathStencilSettings.isTwoSided()); 1864 GrGLenum fillMode = 1865 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 1866 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 1867 1868 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { 1869 GL_CALL(StencilFillPath(id, fillMode, writeMask)); 1870 } 1871 if (stroke.needToApply()) { 1872 GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); 1873 } 1874 1875 if (nonInvertedFill == fill) { 1876 if (stroke.needToApply()) { 1877 GL_CALL(CoverStrokePath(id, GR_GL_BOUNDING_BOX)); 1878 } else { 1879 GL_CALL(CoverFillPath(id, GR_GL_BOUNDING_BOX)); 1880 } 1881 } else { 1882 GrDrawState* drawState = this->drawState(); 1883 GrDrawState::AutoViewMatrixRestore avmr; 1884 SkRect bounds = SkRect::MakeLTRB(0, 0, 1885 SkIntToScalar(drawState->getRenderTarget()->width()), 1886 SkIntToScalar(drawState->getRenderTarget()->height())); 1887 SkMatrix vmi; 1888 // mapRect through persp matrix may not be correct 1889 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { 1890 vmi.mapRect(&bounds); 1891 // theoretically could set bloat = 0, instead leave it because of matrix inversion 1892 // precision. 1893 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; 1894 bounds.outset(bloat, bloat); 1895 } else { 1896 avmr.setIdentity(drawState); 1897 } 1898 1899 this->drawSimpleRect(bounds, NULL); 1900 } 1901} 1902 1903void GrGpuGL::onGpuDrawPaths(int pathCount, const GrPath** paths, 1904 const SkMatrix* transforms, 1905 SkPath::FillType fill, 1906 SkStrokeRec::Style stroke) { 1907 SkASSERT(this->caps()->pathRenderingSupport()); 1908 SkASSERT(NULL != this->drawState()->getRenderTarget()); 1909 SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer()); 1910 SkASSERT(!fCurrentProgram->hasVertexShader()); 1911 SkASSERT(stroke != SkStrokeRec::kHairline_Style); 1912 1913 SkAutoMalloc pathData(pathCount * sizeof(GrGLuint)); 1914 SkAutoMalloc transformData(pathCount * sizeof(GrGLfloat) * 6); 1915 GrGLfloat* transformValues = 1916 reinterpret_cast<GrGLfloat*>(transformData.get()); 1917 GrGLuint* pathIDs = reinterpret_cast<GrGLuint*>(pathData.get()); 1918 1919 for (int i = 0; i < pathCount; ++i) { 1920 SkASSERT(transforms[i].asAffine(NULL)); 1921 const SkMatrix& m = transforms[i]; 1922 transformValues[i * 6] = m.getScaleX(); 1923 transformValues[i * 6 + 1] = m.getSkewY(); 1924 transformValues[i * 6 + 2] = m.getSkewX(); 1925 transformValues[i * 6 + 3] = m.getScaleY(); 1926 transformValues[i * 6 + 4] = m.getTranslateX(); 1927 transformValues[i * 6 + 5] = m.getTranslateY(); 1928 pathIDs[i] = static_cast<const GrGLPath*>(paths[i])->pathID(); 1929 } 1930 1931 flushPathStencilSettings(fill); 1932 1933 SkPath::FillType nonInvertedFill = 1934 SkPath::ConvertToNonInverseFillType(fill); 1935 1936 SkASSERT(!fHWPathStencilSettings.isTwoSided()); 1937 GrGLenum fillMode = 1938 gr_stencil_op_to_gl_path_rendering_fill_mode( 1939 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 1940 GrGLint writeMask = 1941 fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 1942 1943 bool doFill = stroke == SkStrokeRec::kFill_Style 1944 || stroke == SkStrokeRec::kStrokeAndFill_Style; 1945 bool doStroke = stroke == SkStrokeRec::kStroke_Style 1946 || stroke == SkStrokeRec::kStrokeAndFill_Style; 1947 1948 if (doFill) { 1949 GL_CALL(StencilFillPathInstanced(pathCount, GR_GL_UNSIGNED_INT, 1950 pathIDs, 0, 1951 fillMode, writeMask, 1952 GR_GL_AFFINE_2D, transformValues)); 1953 } 1954 if (doStroke) { 1955 GL_CALL(StencilStrokePathInstanced(pathCount, GR_GL_UNSIGNED_INT, 1956 pathIDs, 0, 1957 0xffff, writeMask, 1958 GR_GL_AFFINE_2D, transformValues)); 1959 } 1960 1961 if (nonInvertedFill == fill) { 1962 if (doStroke) { 1963 GL_CALL(CoverStrokePathInstanced( 1964 pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0, 1965 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 1966 GR_GL_AFFINE_2D, transformValues)); 1967 } else { 1968 GL_CALL(CoverFillPathInstanced( 1969 pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0, 1970 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 1971 GR_GL_AFFINE_2D, transformValues)); 1972 1973 } 1974 } else { 1975 GrDrawState* drawState = this->drawState(); 1976 GrDrawState::AutoViewMatrixRestore avmr; 1977 SkRect bounds = SkRect::MakeLTRB(0, 0, 1978 SkIntToScalar(drawState->getRenderTarget()->width()), 1979 SkIntToScalar(drawState->getRenderTarget()->height())); 1980 SkMatrix vmi; 1981 // mapRect through persp matrix may not be correct 1982 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { 1983 vmi.mapRect(&bounds); 1984 // theoretically could set bloat = 0, instead leave it because of matrix inversion 1985 // precision. 1986 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; 1987 bounds.outset(bloat, bloat); 1988 } else { 1989 avmr.setIdentity(drawState); 1990 } 1991 1992 this->drawSimpleRect(bounds, NULL); 1993 } 1994} 1995 1996void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) { 1997 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); 1998 if (rt->needsResolve()) { 1999 // Some extensions automatically resolves the texture when it is read. 2000 if (this->glCaps().usesMSAARenderBuffers()) { 2001 SkASSERT(rt->textureFBOID() != rt->renderFBOID()); 2002 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); 2003 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID())); 2004 // make sure we go through flushRenderTarget() since we've modified 2005 // the bound DRAW FBO ID. 2006 fHWBoundRenderTarget = NULL; 2007 const GrGLIRect& vp = rt->getViewport(); 2008 const SkIRect dirtyRect = rt->getResolveRect(); 2009 GrGLIRect r; 2010 r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop, 2011 dirtyRect.width(), dirtyRect.height(), target->origin()); 2012 2013 GrAutoTRestore<ScissorState> asr; 2014 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { 2015 // Apple's extension uses the scissor as the blit bounds. 2016 asr.reset(&fScissorState); 2017 fScissorState.fEnabled = true; 2018 fScissorState.fRect = dirtyRect; 2019 this->flushScissor(); 2020 GL_CALL(ResolveMultisampleFramebuffer()); 2021 } else { 2022 if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) { 2023 // this respects the scissor during the blit, so disable it. 2024 asr.reset(&fScissorState); 2025 fScissorState.fEnabled = false; 2026 this->flushScissor(); 2027 } 2028 int right = r.fLeft + r.fWidth; 2029 int top = r.fBottom + r.fHeight; 2030 GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top, 2031 r.fLeft, r.fBottom, right, top, 2032 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 2033 } 2034 } 2035 rt->flagAsResolved(); 2036 } 2037} 2038 2039namespace { 2040 2041GrGLenum gr_to_gl_stencil_func(GrStencilFunc basicFunc) { 2042 static const GrGLenum gTable[] = { 2043 GR_GL_ALWAYS, // kAlways_StencilFunc 2044 GR_GL_NEVER, // kNever_StencilFunc 2045 GR_GL_GREATER, // kGreater_StencilFunc 2046 GR_GL_GEQUAL, // kGEqual_StencilFunc 2047 GR_GL_LESS, // kLess_StencilFunc 2048 GR_GL_LEQUAL, // kLEqual_StencilFunc, 2049 GR_GL_EQUAL, // kEqual_StencilFunc, 2050 GR_GL_NOTEQUAL, // kNotEqual_StencilFunc, 2051 }; 2052 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount); 2053 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); 2054 GR_STATIC_ASSERT(1 == kNever_StencilFunc); 2055 GR_STATIC_ASSERT(2 == kGreater_StencilFunc); 2056 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc); 2057 GR_STATIC_ASSERT(4 == kLess_StencilFunc); 2058 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc); 2059 GR_STATIC_ASSERT(6 == kEqual_StencilFunc); 2060 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc); 2061 SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount); 2062 2063 return gTable[basicFunc]; 2064} 2065 2066GrGLenum gr_to_gl_stencil_op(GrStencilOp op) { 2067 static const GrGLenum gTable[] = { 2068 GR_GL_KEEP, // kKeep_StencilOp 2069 GR_GL_REPLACE, // kReplace_StencilOp 2070 GR_GL_INCR_WRAP, // kIncWrap_StencilOp 2071 GR_GL_INCR, // kIncClamp_StencilOp 2072 GR_GL_DECR_WRAP, // kDecWrap_StencilOp 2073 GR_GL_DECR, // kDecClamp_StencilOp 2074 GR_GL_ZERO, // kZero_StencilOp 2075 GR_GL_INVERT, // kInvert_StencilOp 2076 }; 2077 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kStencilOpCount); 2078 GR_STATIC_ASSERT(0 == kKeep_StencilOp); 2079 GR_STATIC_ASSERT(1 == kReplace_StencilOp); 2080 GR_STATIC_ASSERT(2 == kIncWrap_StencilOp); 2081 GR_STATIC_ASSERT(3 == kIncClamp_StencilOp); 2082 GR_STATIC_ASSERT(4 == kDecWrap_StencilOp); 2083 GR_STATIC_ASSERT(5 == kDecClamp_StencilOp); 2084 GR_STATIC_ASSERT(6 == kZero_StencilOp); 2085 GR_STATIC_ASSERT(7 == kInvert_StencilOp); 2086 SkASSERT((unsigned) op < kStencilOpCount); 2087 return gTable[op]; 2088} 2089 2090void set_gl_stencil(const GrGLInterface* gl, 2091 const GrStencilSettings& settings, 2092 GrGLenum glFace, 2093 GrStencilSettings::Face grFace) { 2094 GrGLenum glFunc = gr_to_gl_stencil_func(settings.func(grFace)); 2095 GrGLenum glFailOp = gr_to_gl_stencil_op(settings.failOp(grFace)); 2096 GrGLenum glPassOp = gr_to_gl_stencil_op(settings.passOp(grFace)); 2097 2098 GrGLint ref = settings.funcRef(grFace); 2099 GrGLint mask = settings.funcMask(grFace); 2100 GrGLint writeMask = settings.writeMask(grFace); 2101 2102 if (GR_GL_FRONT_AND_BACK == glFace) { 2103 // we call the combined func just in case separate stencil is not 2104 // supported. 2105 GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask)); 2106 GR_GL_CALL(gl, StencilMask(writeMask)); 2107 GR_GL_CALL(gl, StencilOp(glFailOp, glPassOp, glPassOp)); 2108 } else { 2109 GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask)); 2110 GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask)); 2111 GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, glPassOp, glPassOp)); 2112 } 2113} 2114} 2115 2116void GrGpuGL::flushStencil(DrawType type) { 2117 if (kStencilPath_DrawType != type && fHWStencilSettings != fStencilSettings) { 2118 if (fStencilSettings.isDisabled()) { 2119 if (kNo_TriState != fHWStencilTestEnabled) { 2120 GL_CALL(Disable(GR_GL_STENCIL_TEST)); 2121 fHWStencilTestEnabled = kNo_TriState; 2122 } 2123 } else { 2124 if (kYes_TriState != fHWStencilTestEnabled) { 2125 GL_CALL(Enable(GR_GL_STENCIL_TEST)); 2126 fHWStencilTestEnabled = kYes_TriState; 2127 } 2128 } 2129 if (!fStencilSettings.isDisabled()) { 2130 if (this->caps()->twoSidedStencilSupport()) { 2131 set_gl_stencil(this->glInterface(), 2132 fStencilSettings, 2133 GR_GL_FRONT, 2134 GrStencilSettings::kFront_Face); 2135 set_gl_stencil(this->glInterface(), 2136 fStencilSettings, 2137 GR_GL_BACK, 2138 GrStencilSettings::kBack_Face); 2139 } else { 2140 set_gl_stencil(this->glInterface(), 2141 fStencilSettings, 2142 GR_GL_FRONT_AND_BACK, 2143 GrStencilSettings::kFront_Face); 2144 } 2145 } 2146 fHWStencilSettings = fStencilSettings; 2147 } 2148} 2149 2150void GrGpuGL::flushAAState(DrawType type) { 2151// At least some ATI linux drivers will render GL_LINES incorrectly when MSAA state is enabled but 2152// the target is not multisampled. Single pixel wide lines are rendered thicker than 1 pixel wide. 2153#if 0 2154 // Replace RT_HAS_MSAA with this definition once this driver bug is no longer a relevant concern 2155 #define RT_HAS_MSAA rt->isMultisampled() 2156#else 2157 #define RT_HAS_MSAA (rt->isMultisampled() || kDrawLines_DrawType == type) 2158#endif 2159 2160 const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); 2161 if (kGL_GrGLStandard == this->glStandard()) { 2162 // ES doesn't support toggling GL_MULTISAMPLE and doesn't have 2163 // smooth lines. 2164 // we prefer smooth lines over multisampled lines 2165 bool smoothLines = false; 2166 2167 if (kDrawLines_DrawType == type) { 2168 smoothLines = this->willUseHWAALines(); 2169 if (smoothLines) { 2170 if (kYes_TriState != fHWAAState.fSmoothLineEnabled) { 2171 GL_CALL(Enable(GR_GL_LINE_SMOOTH)); 2172 fHWAAState.fSmoothLineEnabled = kYes_TriState; 2173 // must disable msaa to use line smoothing 2174 if (RT_HAS_MSAA && 2175 kNo_TriState != fHWAAState.fMSAAEnabled) { 2176 GL_CALL(Disable(GR_GL_MULTISAMPLE)); 2177 fHWAAState.fMSAAEnabled = kNo_TriState; 2178 } 2179 } 2180 } else { 2181 if (kNo_TriState != fHWAAState.fSmoothLineEnabled) { 2182 GL_CALL(Disable(GR_GL_LINE_SMOOTH)); 2183 fHWAAState.fSmoothLineEnabled = kNo_TriState; 2184 } 2185 } 2186 } 2187 if (!smoothLines && RT_HAS_MSAA) { 2188 // FIXME: GL_NV_pr doesn't seem to like MSAA disabled. The paths 2189 // convex hulls of each segment appear to get filled. 2190 bool enableMSAA = kStencilPath_DrawType == type || 2191 this->getDrawState().isHWAntialiasState(); 2192 if (enableMSAA) { 2193 if (kYes_TriState != fHWAAState.fMSAAEnabled) { 2194 GL_CALL(Enable(GR_GL_MULTISAMPLE)); 2195 fHWAAState.fMSAAEnabled = kYes_TriState; 2196 } 2197 } else { 2198 if (kNo_TriState != fHWAAState.fMSAAEnabled) { 2199 GL_CALL(Disable(GR_GL_MULTISAMPLE)); 2200 fHWAAState.fMSAAEnabled = kNo_TriState; 2201 } 2202 } 2203 } 2204 } 2205} 2206 2207void GrGpuGL::flushPathStencilSettings(SkPath::FillType fill) { 2208 GrStencilSettings pathStencilSettings; 2209 this->getPathStencilSettingsForFillType(fill, &pathStencilSettings); 2210 if (fHWPathStencilSettings != pathStencilSettings) { 2211 // Just the func, ref, and mask is set here. The op and write mask are params to the call 2212 // that draws the path to the SB (glStencilFillPath) 2213 GrGLenum func = 2214 gr_to_gl_stencil_func(pathStencilSettings.func(GrStencilSettings::kFront_Face)); 2215 GL_CALL(PathStencilFunc(func, 2216 pathStencilSettings.funcRef(GrStencilSettings::kFront_Face), 2217 pathStencilSettings.funcMask(GrStencilSettings::kFront_Face))); 2218 2219 fHWPathStencilSettings = pathStencilSettings; 2220 } 2221} 2222 2223void GrGpuGL::flushBlend(bool isLines, 2224 GrBlendCoeff srcCoeff, 2225 GrBlendCoeff dstCoeff) { 2226 if (isLines && this->willUseHWAALines()) { 2227 if (kYes_TriState != fHWBlendState.fEnabled) { 2228 GL_CALL(Enable(GR_GL_BLEND)); 2229 fHWBlendState.fEnabled = kYes_TriState; 2230 } 2231 if (kSA_GrBlendCoeff != fHWBlendState.fSrcCoeff || 2232 kISA_GrBlendCoeff != fHWBlendState.fDstCoeff) { 2233 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_GrBlendCoeff], 2234 gXfermodeCoeff2Blend[kISA_GrBlendCoeff])); 2235 fHWBlendState.fSrcCoeff = kSA_GrBlendCoeff; 2236 fHWBlendState.fDstCoeff = kISA_GrBlendCoeff; 2237 } 2238 } else { 2239 // any optimization to disable blending should 2240 // have already been applied and tweaked the coeffs 2241 // to (1, 0). 2242 bool blendOff = kOne_GrBlendCoeff == srcCoeff && 2243 kZero_GrBlendCoeff == dstCoeff; 2244 if (blendOff) { 2245 if (kNo_TriState != fHWBlendState.fEnabled) { 2246 GL_CALL(Disable(GR_GL_BLEND)); 2247 fHWBlendState.fEnabled = kNo_TriState; 2248 } 2249 } else { 2250 if (kYes_TriState != fHWBlendState.fEnabled) { 2251 GL_CALL(Enable(GR_GL_BLEND)); 2252 fHWBlendState.fEnabled = kYes_TriState; 2253 } 2254 if (fHWBlendState.fSrcCoeff != srcCoeff || 2255 fHWBlendState.fDstCoeff != dstCoeff) { 2256 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], 2257 gXfermodeCoeff2Blend[dstCoeff])); 2258 fHWBlendState.fSrcCoeff = srcCoeff; 2259 fHWBlendState.fDstCoeff = dstCoeff; 2260 } 2261 GrColor blendConst = this->getDrawState().getBlendConstant(); 2262 if ((BlendCoeffReferencesConstant(srcCoeff) || 2263 BlendCoeffReferencesConstant(dstCoeff)) && 2264 (!fHWBlendState.fConstColorValid || 2265 fHWBlendState.fConstColor != blendConst)) { 2266 GrGLfloat c[4]; 2267 GrColorToRGBAFloat(blendConst, c); 2268 GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); 2269 fHWBlendState.fConstColor = blendConst; 2270 fHWBlendState.fConstColorValid = true; 2271 } 2272 } 2273 } 2274} 2275 2276static inline GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) { 2277 static const GrGLenum gWrapModes[] = { 2278 GR_GL_CLAMP_TO_EDGE, 2279 GR_GL_REPEAT, 2280 GR_GL_MIRRORED_REPEAT 2281 }; 2282 GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes)); 2283 GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode); 2284 GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode); 2285 GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode); 2286 return gWrapModes[tm]; 2287} 2288 2289void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture) { 2290 SkASSERT(NULL != texture); 2291 2292 // If we created a rt/tex and rendered to it without using a texture and now we're texturing 2293 // from the rt it will still be the last bound texture, but it needs resolving. So keep this 2294 // out of the "last != next" check. 2295 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget()); 2296 if (NULL != texRT) { 2297 this->onResolveRenderTarget(texRT); 2298 } 2299 2300 if (fHWBoundTextures[unitIdx] != texture) { 2301 this->setTextureUnit(unitIdx); 2302 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID())); 2303 fHWBoundTextures[unitIdx] = texture; 2304 } 2305 2306 ResetTimestamp timestamp; 2307 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(×tamp); 2308 bool setAll = timestamp < this->getResetTimestamp(); 2309 GrGLTexture::TexParams newTexParams; 2310 2311 static GrGLenum glMinFilterModes[] = { 2312 GR_GL_NEAREST, 2313 GR_GL_LINEAR, 2314 GR_GL_LINEAR_MIPMAP_LINEAR 2315 }; 2316 static GrGLenum glMagFilterModes[] = { 2317 GR_GL_NEAREST, 2318 GR_GL_LINEAR, 2319 GR_GL_LINEAR 2320 }; 2321 GrTextureParams::FilterMode filterMode = params.filterMode(); 2322 if (!this->caps()->mipMapSupport() && GrTextureParams::kMipMap_FilterMode == filterMode) { 2323 filterMode = GrTextureParams::kBilerp_FilterMode; 2324 } 2325 newTexParams.fMinFilter = glMinFilterModes[filterMode]; 2326 newTexParams.fMagFilter = glMagFilterModes[filterMode]; 2327 2328 if (GrTextureParams::kMipMap_FilterMode == filterMode && 2329 texture->mipMapsAreDirty() && !GrPixelConfigIsCompressed(texture->config())) { 2330 GL_CALL(GenerateMipmap(GR_GL_TEXTURE_2D)); 2331 texture->dirtyMipMaps(false); 2332 } 2333 2334 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); 2335 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); 2336 memcpy(newTexParams.fSwizzleRGBA, 2337 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps()), 2338 sizeof(newTexParams.fSwizzleRGBA)); 2339 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { 2340 this->setTextureUnit(unitIdx); 2341 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2342 GR_GL_TEXTURE_MAG_FILTER, 2343 newTexParams.fMagFilter)); 2344 } 2345 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { 2346 this->setTextureUnit(unitIdx); 2347 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2348 GR_GL_TEXTURE_MIN_FILTER, 2349 newTexParams.fMinFilter)); 2350 } 2351 if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { 2352 this->setTextureUnit(unitIdx); 2353 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2354 GR_GL_TEXTURE_WRAP_S, 2355 newTexParams.fWrapS)); 2356 } 2357 if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { 2358 this->setTextureUnit(unitIdx); 2359 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2360 GR_GL_TEXTURE_WRAP_T, 2361 newTexParams.fWrapT)); 2362 } 2363 if (this->glCaps().textureSwizzleSupport() && 2364 (setAll || memcmp(newTexParams.fSwizzleRGBA, 2365 oldTexParams.fSwizzleRGBA, 2366 sizeof(newTexParams.fSwizzleRGBA)))) { 2367 this->setTextureUnit(unitIdx); 2368 if (this->glStandard() == kGLES_GrGLStandard) { 2369 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. 2370 const GrGLenum* swizzle = newTexParams.fSwizzleRGBA; 2371 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); 2372 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); 2373 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); 2374 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); 2375 } else { 2376 GR_STATIC_ASSERT(sizeof(newTexParams.fSwizzleRGBA[0]) == sizeof(GrGLint)); 2377 const GrGLint* swizzle = reinterpret_cast<const GrGLint*>(newTexParams.fSwizzleRGBA); 2378 GL_CALL(TexParameteriv(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle)); 2379 } 2380 } 2381 texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); 2382} 2383 2384void GrGpuGL::setProjectionMatrix(const SkMatrix& matrix, 2385 const SkISize& renderTargetSize, 2386 GrSurfaceOrigin renderTargetOrigin) { 2387 2388 SkASSERT(this->glCaps().pathRenderingSupport()); 2389 2390 if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin && 2391 renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize && 2392 matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) { 2393 return; 2394 } 2395 2396 fHWProjectionMatrixState.fViewMatrix = matrix; 2397 fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize; 2398 fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin; 2399 2400 GrGLfloat glMatrix[4 * 4]; 2401 fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix); 2402 GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix)); 2403} 2404 2405void GrGpuGL::enablePathTexGen(int unitIdx, 2406 PathTexGenComponents components, 2407 const GrGLfloat* coefficients) { 2408 SkASSERT(this->glCaps().pathRenderingSupport()); 2409 SkASSERT(components >= kS_PathTexGenComponents && 2410 components <= kSTR_PathTexGenComponents); 2411 SkASSERT(this->glCaps().maxFixedFunctionTextureCoords() >= unitIdx); 2412 2413 if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode && 2414 components == fHWPathTexGenSettings[unitIdx].fNumComponents && 2415 !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients, 2416 3 * components * sizeof(GrGLfloat))) { 2417 return; 2418 } 2419 2420 this->setTextureUnit(unitIdx); 2421 2422 fHWPathTexGenSettings[unitIdx].fNumComponents = components; 2423 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx, 2424 GR_GL_OBJECT_LINEAR, 2425 components, 2426 coefficients)); 2427 2428 memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients, 2429 3 * components * sizeof(GrGLfloat)); 2430} 2431 2432void GrGpuGL::enablePathTexGen(int unitIdx, PathTexGenComponents components, 2433 const SkMatrix& matrix) { 2434 GrGLfloat coefficients[3 * 3]; 2435 SkASSERT(this->glCaps().pathRenderingSupport()); 2436 SkASSERT(components >= kS_PathTexGenComponents && 2437 components <= kSTR_PathTexGenComponents); 2438 2439 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); 2440 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); 2441 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); 2442 2443 if (components >= kST_PathTexGenComponents) { 2444 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); 2445 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); 2446 coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); 2447 } 2448 2449 if (components >= kSTR_PathTexGenComponents) { 2450 coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); 2451 coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); 2452 coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); 2453 } 2454 2455 enablePathTexGen(unitIdx, components, coefficients); 2456} 2457 2458void GrGpuGL::flushPathTexGenSettings(int numUsedTexCoordSets) { 2459 SkASSERT(this->glCaps().pathRenderingSupport()); 2460 SkASSERT(this->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSets); 2461 2462 // Only write the inactive path tex gens, since active path tex gens were 2463 // written when they were enabled. 2464 2465 SkDEBUGCODE( 2466 for (int i = 0; i < numUsedTexCoordSets; i++) { 2467 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); 2468 } 2469 ); 2470 2471 for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) { 2472 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); 2473 2474 this->setTextureUnit(i); 2475 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); 2476 fHWPathTexGenSettings[i].fNumComponents = 0; 2477 } 2478 2479 fHWActivePathTexGenSets = numUsedTexCoordSets; 2480} 2481 2482void GrGpuGL::flushMiscFixedFunctionState() { 2483 2484 const GrDrawState& drawState = this->getDrawState(); 2485 2486 if (drawState.isDitherState()) { 2487 if (kYes_TriState != fHWDitherEnabled) { 2488 GL_CALL(Enable(GR_GL_DITHER)); 2489 fHWDitherEnabled = kYes_TriState; 2490 } 2491 } else { 2492 if (kNo_TriState != fHWDitherEnabled) { 2493 GL_CALL(Disable(GR_GL_DITHER)); 2494 fHWDitherEnabled = kNo_TriState; 2495 } 2496 } 2497 2498 if (drawState.isColorWriteDisabled()) { 2499 if (kNo_TriState != fHWWriteToColor) { 2500 GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE, 2501 GR_GL_FALSE, GR_GL_FALSE)); 2502 fHWWriteToColor = kNo_TriState; 2503 } 2504 } else { 2505 if (kYes_TriState != fHWWriteToColor) { 2506 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 2507 fHWWriteToColor = kYes_TriState; 2508 } 2509 } 2510 2511 if (fHWDrawFace != drawState.getDrawFace()) { 2512 switch (this->getDrawState().getDrawFace()) { 2513 case GrDrawState::kCCW_DrawFace: 2514 GL_CALL(Enable(GR_GL_CULL_FACE)); 2515 GL_CALL(CullFace(GR_GL_BACK)); 2516 break; 2517 case GrDrawState::kCW_DrawFace: 2518 GL_CALL(Enable(GR_GL_CULL_FACE)); 2519 GL_CALL(CullFace(GR_GL_FRONT)); 2520 break; 2521 case GrDrawState::kBoth_DrawFace: 2522 GL_CALL(Disable(GR_GL_CULL_FACE)); 2523 break; 2524 default: 2525 SkFAIL("Unknown draw face."); 2526 } 2527 fHWDrawFace = drawState.getDrawFace(); 2528 } 2529} 2530 2531void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { 2532 SkASSERT(NULL != renderTarget); 2533 if (fHWBoundRenderTarget == renderTarget) { 2534 fHWBoundRenderTarget = NULL; 2535 } 2536} 2537 2538void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { 2539 for (int s = 0; s < fHWBoundTextures.count(); ++s) { 2540 if (fHWBoundTextures[s] == texture) { 2541 // deleting bound texture does implied bind to 0 2542 fHWBoundTextures[s] = NULL; 2543 } 2544 } 2545} 2546 2547 2548GrGLuint GrGpuGL::createGLPathObject() { 2549 if (NULL == fPathNameAllocator.get()) { 2550 static const int range = 65536; 2551 GrGLuint firstName; 2552 GL_CALL_RET(firstName, GenPaths(range)); 2553 fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range))); 2554 } 2555 2556 GrGLuint name = fPathNameAllocator->allocateName(); 2557 if (0 == name) { 2558 // Our reserved path names are all in use. Fall back on GenPaths. 2559 GL_CALL_RET(name, GenPaths(1)); 2560 } 2561 2562 return name; 2563} 2564 2565void GrGpuGL::deleteGLPathObject(GrGLuint name) { 2566 if (NULL == fPathNameAllocator.get() || 2567 name < fPathNameAllocator->firstName() || 2568 name >= fPathNameAllocator->endName()) { 2569 // If we aren't inside fPathNameAllocator's range then this name was 2570 // generated by the GenPaths fallback (or else the name is unallocated). 2571 GL_CALL(DeletePaths(name, 1)); 2572 return; 2573 } 2574 2575 // Make the path empty to save memory, but don't free the name in the driver. 2576 GL_CALL(PathCommands(name, 0, NULL, 0, GR_GL_FLOAT, NULL)); 2577 fPathNameAllocator->free(name); 2578} 2579 2580bool GrGpuGL::configToGLFormats(GrPixelConfig config, 2581 bool getSizedInternalFormat, 2582 GrGLenum* internalFormat, 2583 GrGLenum* externalFormat, 2584 GrGLenum* externalType) { 2585 GrGLenum dontCare; 2586 if (NULL == internalFormat) { 2587 internalFormat = &dontCare; 2588 } 2589 if (NULL == externalFormat) { 2590 externalFormat = &dontCare; 2591 } 2592 if (NULL == externalType) { 2593 externalType = &dontCare; 2594 } 2595 2596 if(!this->glCaps().isConfigTexturable(config)) { 2597 return false; 2598 } 2599 2600 switch (config) { 2601 case kRGBA_8888_GrPixelConfig: 2602 *internalFormat = GR_GL_RGBA; 2603 *externalFormat = GR_GL_RGBA; 2604 if (getSizedInternalFormat) { 2605 *internalFormat = GR_GL_RGBA8; 2606 } else { 2607 *internalFormat = GR_GL_RGBA; 2608 } 2609 *externalType = GR_GL_UNSIGNED_BYTE; 2610 break; 2611 case kBGRA_8888_GrPixelConfig: 2612 if (this->glCaps().bgraIsInternalFormat()) { 2613 if (getSizedInternalFormat) { 2614 *internalFormat = GR_GL_BGRA8; 2615 } else { 2616 *internalFormat = GR_GL_BGRA; 2617 } 2618 } else { 2619 if (getSizedInternalFormat) { 2620 *internalFormat = GR_GL_RGBA8; 2621 } else { 2622 *internalFormat = GR_GL_RGBA; 2623 } 2624 } 2625 *externalFormat = GR_GL_BGRA; 2626 *externalType = GR_GL_UNSIGNED_BYTE; 2627 break; 2628 case kRGB_565_GrPixelConfig: 2629 *internalFormat = GR_GL_RGB; 2630 *externalFormat = GR_GL_RGB; 2631 if (getSizedInternalFormat) { 2632 if (this->glStandard() == kGL_GrGLStandard) { 2633 return false; 2634 } else { 2635 *internalFormat = GR_GL_RGB565; 2636 } 2637 } else { 2638 *internalFormat = GR_GL_RGB; 2639 } 2640 *externalType = GR_GL_UNSIGNED_SHORT_5_6_5; 2641 break; 2642 case kRGBA_4444_GrPixelConfig: 2643 *internalFormat = GR_GL_RGBA; 2644 *externalFormat = GR_GL_RGBA; 2645 if (getSizedInternalFormat) { 2646 *internalFormat = GR_GL_RGBA4; 2647 } else { 2648 *internalFormat = GR_GL_RGBA; 2649 } 2650 *externalType = GR_GL_UNSIGNED_SHORT_4_4_4_4; 2651 break; 2652 case kIndex_8_GrPixelConfig: 2653 // glCompressedTexImage doesn't take external params 2654 *externalFormat = GR_GL_PALETTE8_RGBA8; 2655 // no sized/unsized internal format distinction here 2656 *internalFormat = GR_GL_PALETTE8_RGBA8; 2657 // unused with CompressedTexImage 2658 *externalType = GR_GL_UNSIGNED_BYTE; 2659 break; 2660 case kAlpha_8_GrPixelConfig: 2661 if (this->glCaps().textureRedSupport()) { 2662 *internalFormat = GR_GL_RED; 2663 *externalFormat = GR_GL_RED; 2664 if (getSizedInternalFormat) { 2665 *internalFormat = GR_GL_R8; 2666 } else { 2667 *internalFormat = GR_GL_RED; 2668 } 2669 *externalType = GR_GL_UNSIGNED_BYTE; 2670 } else { 2671 *internalFormat = GR_GL_ALPHA; 2672 *externalFormat = GR_GL_ALPHA; 2673 if (getSizedInternalFormat) { 2674 *internalFormat = GR_GL_ALPHA8; 2675 } else { 2676 *internalFormat = GR_GL_ALPHA; 2677 } 2678 *externalType = GR_GL_UNSIGNED_BYTE; 2679 } 2680 break; 2681 case kETC1_GrPixelConfig: 2682 *internalFormat = GR_GL_COMPRESSED_RGB8_ETC1; 2683 break; 2684 case kLATC_GrPixelConfig: 2685 switch(this->glCaps().latcAlias()) { 2686 case GrGLCaps::kLATC_LATCAlias: 2687 *internalFormat = GR_GL_COMPRESSED_LUMINANCE_LATC1; 2688 break; 2689 case GrGLCaps::kRGTC_LATCAlias: 2690 *internalFormat = GR_GL_COMPRESSED_RED_RGTC1; 2691 break; 2692 case GrGLCaps::k3DC_LATCAlias: 2693 *internalFormat = GR_GL_COMPRESSED_3DC_X; 2694 break; 2695 } 2696 break; 2697 default: 2698 return false; 2699 } 2700 return true; 2701} 2702 2703void GrGpuGL::setTextureUnit(int unit) { 2704 SkASSERT(unit >= 0 && unit < fHWBoundTextures.count()); 2705 if (unit != fHWActiveTextureUnitIdx) { 2706 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit)); 2707 fHWActiveTextureUnitIdx = unit; 2708 } 2709} 2710 2711void GrGpuGL::setScratchTextureUnit() { 2712 // Bind the last texture unit since it is the least likely to be used by GrGLProgram. 2713 int lastUnitIdx = fHWBoundTextures.count() - 1; 2714 if (lastUnitIdx != fHWActiveTextureUnitIdx) { 2715 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx)); 2716 fHWActiveTextureUnitIdx = lastUnitIdx; 2717 } 2718 // clear out the this field so that if a program does use this unit it will rebind the correct 2719 // texture. 2720 fHWBoundTextures[lastUnitIdx] = NULL; 2721} 2722 2723namespace { 2724// Determines whether glBlitFramebuffer could be used between src and dst. 2725inline bool can_blit_framebuffer(const GrSurface* dst, 2726 const GrSurface* src, 2727 const GrGpuGL* gpu, 2728 bool* wouldNeedTempFBO = NULL) { 2729 if (gpu->glCaps().isConfigRenderable(dst->config(), dst->desc().fSampleCnt > 0) && 2730 gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) && 2731 gpu->glCaps().usesMSAARenderBuffers()) { 2732 // ES3 doesn't allow framebuffer blits when the src has MSAA and the configs don't match 2733 // or the rects are not the same (not just the same size but have the same edges). 2734 if (GrGLCaps::kES_3_0_MSFBOType == gpu->glCaps().msFBOType() && 2735 (src->desc().fSampleCnt > 0 || src->config() != dst->config())) { 2736 return false; 2737 } 2738 if (NULL != wouldNeedTempFBO) { 2739 *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->asRenderTarget(); 2740 } 2741 return true; 2742 } else { 2743 return false; 2744 } 2745} 2746 2747inline bool can_copy_texsubimage(const GrSurface* dst, 2748 const GrSurface* src, 2749 const GrGpuGL* gpu, 2750 bool* wouldNeedTempFBO = NULL) { 2751 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage 2752 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps 2753 // many drivers would allow it to work, but ANGLE does not. 2754 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalFormat() && 2755 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig == src->config())) { 2756 return false; 2757 } 2758 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget()); 2759 // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer) 2760 // then we don't want to copy to the texture but to the MSAA buffer. 2761 if (NULL != dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { 2762 return false; 2763 } 2764 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget()); 2765 // If the src is multisampled (and uses an extension where there is a separate MSAA 2766 // renderbuffer) then it is an invalid operation to call CopyTexSubImage 2767 if (NULL != srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { 2768 return false; 2769 } 2770 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) && 2771 NULL != dst->asTexture() && 2772 dst->origin() == src->origin() && 2773 kIndex_8_GrPixelConfig != src->config() && 2774 !GrPixelConfigIsCompressed(src->config())) { 2775 if (NULL != wouldNeedTempFBO) { 2776 *wouldNeedTempFBO = NULL == src->asRenderTarget(); 2777 } 2778 return true; 2779 } else { 2780 return false; 2781 } 2782} 2783 2784// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is 2785// relative to is output. 2786inline GrGLuint bind_surface_as_fbo(const GrGLInterface* gl, 2787 GrSurface* surface, 2788 GrGLenum fboTarget, 2789 GrGLIRect* viewport) { 2790 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget()); 2791 GrGLuint tempFBOID; 2792 if (NULL == rt) { 2793 SkASSERT(NULL != surface->asTexture()); 2794 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID(); 2795 GR_GL_CALL(gl, GenFramebuffers(1, &tempFBOID)); 2796 GR_GL_CALL(gl, BindFramebuffer(fboTarget, tempFBOID)); 2797 GR_GL_CALL(gl, FramebufferTexture2D(fboTarget, 2798 GR_GL_COLOR_ATTACHMENT0, 2799 GR_GL_TEXTURE_2D, 2800 texID, 2801 0)); 2802 viewport->fLeft = 0; 2803 viewport->fBottom = 0; 2804 viewport->fWidth = surface->width(); 2805 viewport->fHeight = surface->height(); 2806 } else { 2807 tempFBOID = 0; 2808 GR_GL_CALL(gl, BindFramebuffer(fboTarget, rt->renderFBOID())); 2809 *viewport = rt->getViewport(); 2810 } 2811 return tempFBOID; 2812} 2813 2814} 2815 2816void GrGpuGL::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) { 2817 // Check for format issues with glCopyTexSubImage2D 2818 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInternalFormat() && 2819 kBGRA_8888_GrPixelConfig == src->config()) { 2820 // glCopyTexSubImage2D doesn't work with this config. We'll want to make it a render target 2821 // in order to call glBlitFramebuffer or to copy to it by rendering. 2822 INHERITED::initCopySurfaceDstDesc(src, desc); 2823 return; 2824 } else if (NULL == src->asRenderTarget()) { 2825 // We don't want to have to create an FBO just to use glCopyTexSubImage2D. Let the base 2826 // class handle it by rendering. 2827 INHERITED::initCopySurfaceDstDesc(src, desc); 2828 return; 2829 } 2830 2831 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget()); 2832 if (NULL != srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { 2833 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. 2834 INHERITED::initCopySurfaceDstDesc(src, desc); 2835 } else { 2836 desc->fConfig = src->config(); 2837 desc->fOrigin = src->origin(); 2838 desc->fFlags = kNone_GrTextureFlags; 2839 } 2840} 2841 2842bool GrGpuGL::onCopySurface(GrSurface* dst, 2843 GrSurface* src, 2844 const SkIRect& srcRect, 2845 const SkIPoint& dstPoint) { 2846 bool inheritedCouldCopy = INHERITED::onCanCopySurface(dst, src, srcRect, dstPoint); 2847 bool copied = false; 2848 bool wouldNeedTempFBO = false; 2849 if (can_copy_texsubimage(dst, src, this, &wouldNeedTempFBO) && 2850 (!wouldNeedTempFBO || !inheritedCouldCopy)) { 2851 GrGLuint srcFBO; 2852 GrGLIRect srcVP; 2853 srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_FRAMEBUFFER, &srcVP); 2854 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); 2855 SkASSERT(NULL != dstTex); 2856 // We modified the bound FBO 2857 fHWBoundRenderTarget = NULL; 2858 GrGLIRect srcGLRect; 2859 srcGLRect.setRelativeTo(srcVP, 2860 srcRect.fLeft, 2861 srcRect.fTop, 2862 srcRect.width(), 2863 srcRect.height(), 2864 src->origin()); 2865 2866 this->setScratchTextureUnit(); 2867 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); 2868 GrGLint dstY; 2869 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { 2870 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); 2871 } else { 2872 dstY = dstPoint.fY; 2873 } 2874 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, 2875 dstPoint.fX, dstY, 2876 srcGLRect.fLeft, srcGLRect.fBottom, 2877 srcGLRect.fWidth, srcGLRect.fHeight)); 2878 copied = true; 2879 if (srcFBO) { 2880 GL_CALL(DeleteFramebuffers(1, &srcFBO)); 2881 } 2882 } else if (can_blit_framebuffer(dst, src, this, &wouldNeedTempFBO) && 2883 (!wouldNeedTempFBO || !inheritedCouldCopy)) { 2884 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 2885 srcRect.width(), srcRect.height()); 2886 bool selfOverlap = false; 2887 if (dst->isSameAs(src)) { 2888 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); 2889 } 2890 2891 if (!selfOverlap) { 2892 GrGLuint dstFBO; 2893 GrGLuint srcFBO; 2894 GrGLIRect dstVP; 2895 GrGLIRect srcVP; 2896 dstFBO = bind_surface_as_fbo(this->glInterface(), dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP); 2897 srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_READ_FRAMEBUFFER, &srcVP); 2898 // We modified the bound FBO 2899 fHWBoundRenderTarget = NULL; 2900 GrGLIRect srcGLRect; 2901 GrGLIRect dstGLRect; 2902 srcGLRect.setRelativeTo(srcVP, 2903 srcRect.fLeft, 2904 srcRect.fTop, 2905 srcRect.width(), 2906 srcRect.height(), 2907 src->origin()); 2908 dstGLRect.setRelativeTo(dstVP, 2909 dstRect.fLeft, 2910 dstRect.fTop, 2911 dstRect.width(), 2912 dstRect.height(), 2913 dst->origin()); 2914 2915 GrAutoTRestore<ScissorState> asr; 2916 if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) { 2917 // The EXT version applies the scissor during the blit, so disable it. 2918 asr.reset(&fScissorState); 2919 fScissorState.fEnabled = false; 2920 this->flushScissor(); 2921 } 2922 GrGLint srcY0; 2923 GrGLint srcY1; 2924 // Does the blit need to y-mirror or not? 2925 if (src->origin() == dst->origin()) { 2926 srcY0 = srcGLRect.fBottom; 2927 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; 2928 } else { 2929 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; 2930 srcY1 = srcGLRect.fBottom; 2931 } 2932 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, 2933 srcY0, 2934 srcGLRect.fLeft + srcGLRect.fWidth, 2935 srcY1, 2936 dstGLRect.fLeft, 2937 dstGLRect.fBottom, 2938 dstGLRect.fLeft + dstGLRect.fWidth, 2939 dstGLRect.fBottom + dstGLRect.fHeight, 2940 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 2941 if (dstFBO) { 2942 GL_CALL(DeleteFramebuffers(1, &dstFBO)); 2943 } 2944 if (srcFBO) { 2945 GL_CALL(DeleteFramebuffers(1, &srcFBO)); 2946 } 2947 copied = true; 2948 } 2949 } 2950 if (!copied && inheritedCouldCopy) { 2951 copied = INHERITED::onCopySurface(dst, src, srcRect, dstPoint); 2952 SkASSERT(copied); 2953 } 2954 return copied; 2955} 2956 2957bool GrGpuGL::onCanCopySurface(GrSurface* dst, 2958 GrSurface* src, 2959 const SkIRect& srcRect, 2960 const SkIPoint& dstPoint) { 2961 // This mirrors the logic in onCopySurface. 2962 if (can_copy_texsubimage(dst, src, this)) { 2963 return true; 2964 } 2965 if (can_blit_framebuffer(dst, src, this)) { 2966 if (dst->isSameAs(src)) { 2967 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 2968 srcRect.width(), srcRect.height()); 2969 if(!SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { 2970 return true; 2971 } 2972 } else { 2973 return true; 2974 } 2975 } 2976 return INHERITED::onCanCopySurface(dst, src, srcRect, dstPoint); 2977} 2978 2979void GrGpuGL::didAddGpuTraceMarker() { 2980 if (this->caps()->gpuTracingSupport()) { 2981 const GrTraceMarkerSet& markerArray = this->getActiveTraceMarkers(); 2982 SkString markerString = markerArray.toString(); 2983 GL_CALL(PushGroupMarker(0, markerString.c_str())); 2984 } 2985} 2986 2987void GrGpuGL::didRemoveGpuTraceMarker() { 2988 if (this->caps()->gpuTracingSupport()) { 2989 GL_CALL(PopGroupMarker()); 2990 } 2991} 2992/////////////////////////////////////////////////////////////////////////////// 2993 2994GrGLAttribArrayState* GrGpuGL::HWGeometryState::bindArrayAndBuffersToDraw( 2995 GrGpuGL* gpu, 2996 const GrGLVertexBuffer* vbuffer, 2997 const GrGLIndexBuffer* ibuffer) { 2998 SkASSERT(NULL != vbuffer); 2999 GrGLAttribArrayState* attribState; 3000 3001 // We use a vertex array if we're on a core profile and the verts are in a VBO. 3002 if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) { 3003 if (NULL == fVBOVertexArray || fVBOVertexArray->wasDestroyed()) { 3004 SkSafeUnref(fVBOVertexArray); 3005 GrGLuint arrayID; 3006 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); 3007 int attrCount = gpu->glCaps().maxVertexAttributes(); 3008 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (gpu, arrayID, attrCount)); 3009 } 3010 attribState = fVBOVertexArray->bindWithIndexBuffer(ibuffer); 3011 } else { 3012 if (NULL != ibuffer) { 3013 this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID()); 3014 } else { 3015 this->setVertexArrayID(gpu, 0); 3016 } 3017 int attrCount = gpu->glCaps().maxVertexAttributes(); 3018 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3019 fDefaultVertexArrayAttribState.resize(attrCount); 3020 } 3021 attribState = &fDefaultVertexArrayAttribState; 3022 } 3023 return attribState; 3024} 3025