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 #include "GrGLGpu.h" 9 10 #include <cmath> 11 #include "../private/GrGLSL.h" 12 #include "GrBackendSemaphore.h" 13 #include "GrBackendSurface.h" 14 #include "GrFixedClip.h" 15 #include "GrGLBuffer.h" 16 #include "GrGLGpuCommandBuffer.h" 17 #include "GrGLSemaphore.h" 18 #include "GrGLStencilAttachment.h" 19 #include "GrGLTextureRenderTarget.h" 20 #include "GrGpuResourcePriv.h" 21 #include "GrMesh.h" 22 #include "GrPipeline.h" 23 #include "GrRenderTargetPriv.h" 24 #include "GrShaderCaps.h" 25 #include "GrSurfaceProxyPriv.h" 26 #include "GrTexturePriv.h" 27 #include "GrTypes.h" 28 #include "SkAutoMalloc.h" 29 #include "SkHalf.h" 30 #include "SkJSONWriter.h" 31 #include "SkMakeUnique.h" 32 #include "SkMipMap.h" 33 #include "SkPixmap.h" 34 #include "SkSLCompiler.h" 35 #include "SkStrokeRec.h" 36 #include "SkTemplates.h" 37 #include "SkTraceEvent.h" 38 #include "SkTypes.h" 39 #include "builders/GrGLShaderStringBuilder.h" 40 41 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) 42 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) 43 44 #define SKIP_CACHE_CHECK true 45 46 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR 47 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) 48 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) 49 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) 50 #else 51 #define CLEAR_ERROR_BEFORE_ALLOC(iface) 52 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call) 53 #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR 54 #endif 55 56 //#define USE_NSIGHT 57 58 /////////////////////////////////////////////////////////////////////////////// 59 60 static const GrGLenum gXfermodeEquation2Blend[] = { 61 // Basic OpenGL blend equations. 62 GR_GL_FUNC_ADD, 63 GR_GL_FUNC_SUBTRACT, 64 GR_GL_FUNC_REVERSE_SUBTRACT, 65 66 // GL_KHR_blend_equation_advanced. 67 GR_GL_SCREEN, 68 GR_GL_OVERLAY, 69 GR_GL_DARKEN, 70 GR_GL_LIGHTEN, 71 GR_GL_COLORDODGE, 72 GR_GL_COLORBURN, 73 GR_GL_HARDLIGHT, 74 GR_GL_SOFTLIGHT, 75 GR_GL_DIFFERENCE, 76 GR_GL_EXCLUSION, 77 GR_GL_MULTIPLY, 78 GR_GL_HSL_HUE, 79 GR_GL_HSL_SATURATION, 80 GR_GL_HSL_COLOR, 81 GR_GL_HSL_LUMINOSITY 82 }; 83 GR_STATIC_ASSERT(0 == kAdd_GrBlendEquation); 84 GR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation); 85 GR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation); 86 GR_STATIC_ASSERT(3 == kScreen_GrBlendEquation); 87 GR_STATIC_ASSERT(4 == kOverlay_GrBlendEquation); 88 GR_STATIC_ASSERT(5 == kDarken_GrBlendEquation); 89 GR_STATIC_ASSERT(6 == kLighten_GrBlendEquation); 90 GR_STATIC_ASSERT(7 == kColorDodge_GrBlendEquation); 91 GR_STATIC_ASSERT(8 == kColorBurn_GrBlendEquation); 92 GR_STATIC_ASSERT(9 == kHardLight_GrBlendEquation); 93 GR_STATIC_ASSERT(10 == kSoftLight_GrBlendEquation); 94 GR_STATIC_ASSERT(11 == kDifference_GrBlendEquation); 95 GR_STATIC_ASSERT(12 == kExclusion_GrBlendEquation); 96 GR_STATIC_ASSERT(13 == kMultiply_GrBlendEquation); 97 GR_STATIC_ASSERT(14 == kHSLHue_GrBlendEquation); 98 GR_STATIC_ASSERT(15 == kHSLSaturation_GrBlendEquation); 99 GR_STATIC_ASSERT(16 == kHSLColor_GrBlendEquation); 100 GR_STATIC_ASSERT(17 == kHSLLuminosity_GrBlendEquation); 101 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gXfermodeEquation2Blend) == kGrBlendEquationCnt); 102 103 static const GrGLenum gXfermodeCoeff2Blend[] = { 104 GR_GL_ZERO, 105 GR_GL_ONE, 106 GR_GL_SRC_COLOR, 107 GR_GL_ONE_MINUS_SRC_COLOR, 108 GR_GL_DST_COLOR, 109 GR_GL_ONE_MINUS_DST_COLOR, 110 GR_GL_SRC_ALPHA, 111 GR_GL_ONE_MINUS_SRC_ALPHA, 112 GR_GL_DST_ALPHA, 113 GR_GL_ONE_MINUS_DST_ALPHA, 114 GR_GL_CONSTANT_COLOR, 115 GR_GL_ONE_MINUS_CONSTANT_COLOR, 116 GR_GL_CONSTANT_ALPHA, 117 GR_GL_ONE_MINUS_CONSTANT_ALPHA, 118 119 // extended blend coeffs 120 GR_GL_SRC1_COLOR, 121 GR_GL_ONE_MINUS_SRC1_COLOR, 122 GR_GL_SRC1_ALPHA, 123 GR_GL_ONE_MINUS_SRC1_ALPHA, 124 }; 125 126 bool GrGLGpu::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { 127 static const bool gCoeffReferencesBlendConst[] = { 128 false, 129 false, 130 false, 131 false, 132 false, 133 false, 134 false, 135 false, 136 false, 137 false, 138 true, 139 true, 140 true, 141 true, 142 143 // extended blend coeffs 144 false, 145 false, 146 false, 147 false, 148 }; 149 return gCoeffReferencesBlendConst[coeff]; 150 GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendConst)); 151 152 GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff); 153 GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff); 154 GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff); 155 GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff); 156 GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff); 157 GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff); 158 GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff); 159 GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff); 160 GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff); 161 GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff); 162 GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff); 163 GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff); 164 GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff); 165 GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff); 166 167 GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff); 168 GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff); 169 GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff); 170 GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff); 171 172 // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope 173 GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gXfermodeCoeff2Blend)); 174 } 175 176 /////////////////////////////////////////////////////////////////////////////// 177 178 sk_sp<GrGpu> GrGLGpu::Make(GrBackendContext backendContext, const GrContextOptions& options, 179 GrContext* context) { 180 const auto* interface = reinterpret_cast<const GrGLInterface*>(backendContext); 181 return Make(sk_ref_sp(interface), options, context); 182 } 183 184 sk_sp<GrGpu> GrGLGpu::Make(sk_sp<const GrGLInterface> interface, const GrContextOptions& options, 185 GrContext* context) { 186 if (!interface) { 187 interface = GrGLMakeNativeInterface(); 188 // For clients that have written their own GrGLCreateNativeInterface and haven't yet updated 189 // to GrGLMakeNativeInterface. 190 if (!interface) { 191 interface = sk_ref_sp(GrGLCreateNativeInterface()); 192 } 193 if (!interface) { 194 return nullptr; 195 } 196 } 197 #ifdef USE_NSIGHT 198 const_cast<GrContextOptions&>(options).fSuppressPathRendering = true; 199 #endif 200 auto glContext = GrGLContext::Make(std::move(interface), options); 201 if (!glContext) { 202 return nullptr; 203 } 204 return sk_sp<GrGpu>(new GrGLGpu(std::move(glContext), context)); 205 } 206 207 GrGLGpu::GrGLGpu(std::unique_ptr<GrGLContext> ctx, GrContext* context) 208 : GrGpu(context) 209 , fGLContext(std::move(ctx)) 210 , fProgramCache(new ProgramCache(this)) 211 , fHWProgramID(0) 212 , fTempSrcFBOID(0) 213 , fTempDstFBOID(0) 214 , fStencilClearFBOID(0) 215 , fHWMaxUsedBufferTextureUnit(-1) 216 , fHWMinSampleShading(0.0) { 217 SkASSERT(fGLContext); 218 fCaps = sk_ref_sp(fGLContext->caps()); 219 220 fHWBoundTextureUniqueIDs.reset(this->caps()->shaderCaps()->maxCombinedSamplers()); 221 222 fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER; 223 fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER; 224 fHWBufferState[kTexel_GrBufferType].fGLTarget = GR_GL_TEXTURE_BUFFER; 225 fHWBufferState[kDrawIndirect_GrBufferType].fGLTarget = GR_GL_DRAW_INDIRECT_BUFFER; 226 if (GrGLCaps::kChromium_TransferBufferType == this->glCaps().transferBufferType()) { 227 fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = 228 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM; 229 fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = 230 GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM; 231 } else { 232 fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = GR_GL_PIXEL_UNPACK_BUFFER; 233 fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = GR_GL_PIXEL_PACK_BUFFER; 234 } 235 for (int i = 0; i < kGrBufferTypeCount; ++i) { 236 fHWBufferState[i].invalidate(); 237 } 238 GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState)); 239 240 if (this->caps()->shaderCaps()->texelBufferSupport()) { 241 fHWBufferTextures.reset(this->caps()->shaderCaps()->maxCombinedSamplers()); 242 } 243 244 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 245 fPathRendering.reset(new GrGLPathRendering(this)); 246 } 247 248 GrGLClearErr(this->glInterface()); 249 } 250 251 GrGLGpu::~GrGLGpu() { 252 // Ensure any GrGpuResource objects get deleted first, since they may require a working GrGLGpu 253 // to release the resources held by the objects themselves. 254 fPathRendering.reset(); 255 fCopyProgramArrayBuffer.reset(); 256 fMipmapProgramArrayBuffer.reset(); 257 fStencilClipClearArrayBuffer.reset(); 258 259 if (fHWProgramID) { 260 // detach the current program so there is no confusion on OpenGL's part 261 // that we want it to be deleted 262 GL_CALL(UseProgram(0)); 263 } 264 265 if (fTempSrcFBOID) { 266 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); 267 } 268 if (fTempDstFBOID) { 269 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); 270 } 271 if (fStencilClearFBOID) { 272 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); 273 } 274 275 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { 276 if (0 != fCopyPrograms[i].fProgram) { 277 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); 278 } 279 } 280 281 for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { 282 if (0 != fMipmapPrograms[i].fProgram) { 283 GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram)); 284 } 285 } 286 287 if (fStencilClipClearProgram) { 288 GL_CALL(DeleteProgram(fStencilClipClearProgram)); 289 } 290 291 if (fClearColorProgram.fProgram) { 292 GL_CALL(DeleteProgram(fClearColorProgram.fProgram)); 293 } 294 295 delete fProgramCache; 296 } 297 298 void GrGLGpu::disconnect(DisconnectType type) { 299 INHERITED::disconnect(type); 300 if (DisconnectType::kCleanup == type) { 301 if (fHWProgramID) { 302 GL_CALL(UseProgram(0)); 303 } 304 if (fTempSrcFBOID) { 305 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); 306 } 307 if (fTempDstFBOID) { 308 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); 309 } 310 if (fStencilClearFBOID) { 311 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); 312 } 313 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { 314 if (fCopyPrograms[i].fProgram) { 315 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); 316 } 317 } 318 for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { 319 if (fMipmapPrograms[i].fProgram) { 320 GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram)); 321 } 322 } 323 if (fStencilClipClearProgram) { 324 GL_CALL(DeleteProgram(fStencilClipClearProgram)); 325 } 326 327 if (fClearColorProgram.fProgram) { 328 GL_CALL(DeleteProgram(fClearColorProgram.fProgram)); 329 } 330 } else { 331 if (fProgramCache) { 332 fProgramCache->abandon(); 333 } 334 } 335 336 delete fProgramCache; 337 fProgramCache = nullptr; 338 339 fHWProgramID = 0; 340 fTempSrcFBOID = 0; 341 fTempDstFBOID = 0; 342 fStencilClearFBOID = 0; 343 fCopyProgramArrayBuffer.reset(); 344 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { 345 fCopyPrograms[i].fProgram = 0; 346 } 347 fMipmapProgramArrayBuffer.reset(); 348 for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { 349 fMipmapPrograms[i].fProgram = 0; 350 } 351 fStencilClipClearProgram = 0; 352 fStencilClipClearArrayBuffer.reset(); 353 fClearColorProgram.fProgram = 0; 354 355 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 356 this->glPathRendering()->disconnect(type); 357 } 358 } 359 360 /////////////////////////////////////////////////////////////////////////////// 361 362 void GrGLGpu::onResetContext(uint32_t resetBits) { 363 if (resetBits & kMisc_GrGLBackendState) { 364 // we don't use the zb at all 365 GL_CALL(Disable(GR_GL_DEPTH_TEST)); 366 GL_CALL(DepthMask(GR_GL_FALSE)); 367 368 // We don't use face culling. 369 GL_CALL(Disable(GR_GL_CULL_FACE)); 370 // We do use separate stencil. Our algorithms don't care which face is front vs. back so 371 // just set this to the default for self-consistency. 372 GL_CALL(FrontFace(GR_GL_CCW)); 373 374 fHWBufferState[kTexel_GrBufferType].invalidate(); 375 fHWBufferState[kDrawIndirect_GrBufferType].invalidate(); 376 fHWBufferState[kXferCpuToGpu_GrBufferType].invalidate(); 377 fHWBufferState[kXferGpuToCpu_GrBufferType].invalidate(); 378 379 if (kGL_GrGLStandard == this->glStandard()) { 380 #ifndef USE_NSIGHT 381 // Desktop-only state that we never change 382 if (!this->glCaps().isCoreProfile()) { 383 GL_CALL(Disable(GR_GL_POINT_SMOOTH)); 384 GL_CALL(Disable(GR_GL_LINE_SMOOTH)); 385 GL_CALL(Disable(GR_GL_POLYGON_SMOOTH)); 386 GL_CALL(Disable(GR_GL_POLYGON_STIPPLE)); 387 GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP)); 388 GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP)); 389 } 390 // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a 391 // core profile. This seems like a bug since the core spec removes any mention of 392 // GL_ARB_imaging. 393 if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) { 394 GL_CALL(Disable(GR_GL_COLOR_TABLE)); 395 } 396 GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL)); 397 398 if (this->caps()->wireframeMode()) { 399 GL_CALL(PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_LINE)); 400 } else { 401 GL_CALL(PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_FILL)); 402 } 403 #endif 404 // Since ES doesn't support glPointSize at all we always use the VS to 405 // set the point size 406 GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE)); 407 408 } 409 410 if (kGLES_GrGLStandard == this->glStandard() && 411 this->hasExtension("GL_ARM_shader_framebuffer_fetch")) { 412 // The arm extension requires specifically enabling MSAA fetching per sample. 413 // On some devices this may have a perf hit. Also multiple render targets are disabled 414 GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM)); 415 } 416 fHWWriteToColor = kUnknown_TriState; 417 // we only ever use lines in hairline mode 418 GL_CALL(LineWidth(1)); 419 GL_CALL(Disable(GR_GL_DITHER)); 420 } 421 422 if (resetBits & kMSAAEnable_GrGLBackendState) { 423 fMSAAEnabled = kUnknown_TriState; 424 425 if (this->caps()->usesMixedSamples()) { 426 if (0 != this->caps()->maxRasterSamples()) { 427 fHWRasterMultisampleEnabled = kUnknown_TriState; 428 fHWNumRasterSamples = 0; 429 } 430 431 // The skia blend modes all use premultiplied alpha and therefore expect RGBA coverage 432 // modulation. This state has no effect when not rendering to a mixed sampled target. 433 GL_CALL(CoverageModulation(GR_GL_RGBA)); 434 } 435 } 436 437 fHWActiveTextureUnitIdx = -1; // invalid 438 fLastPrimitiveType = static_cast<GrPrimitiveType>(-1); 439 440 if (resetBits & kTextureBinding_GrGLBackendState) { 441 for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) { 442 fHWBoundTextureUniqueIDs[s].makeInvalid(); 443 } 444 for (int b = 0; b < fHWBufferTextures.count(); ++b) { 445 SkASSERT(this->caps()->shaderCaps()->texelBufferSupport()); 446 fHWBufferTextures[b].fKnownBound = false; 447 } 448 } 449 450 if (resetBits & kBlend_GrGLBackendState) { 451 fHWBlendState.invalidate(); 452 } 453 454 if (resetBits & kView_GrGLBackendState) { 455 fHWScissorSettings.invalidate(); 456 fHWWindowRectsState.invalidate(); 457 fHWViewport.invalidate(); 458 } 459 460 if (resetBits & kStencil_GrGLBackendState) { 461 fHWStencilSettings.invalidate(); 462 fHWStencilTestEnabled = kUnknown_TriState; 463 } 464 465 // Vertex 466 if (resetBits & kVertex_GrGLBackendState) { 467 fHWVertexArrayState.invalidate(); 468 fHWBufferState[kVertex_GrBufferType].invalidate(); 469 fHWBufferState[kIndex_GrBufferType].invalidate(); 470 } 471 472 if (resetBits & kRenderTarget_GrGLBackendState) { 473 fHWBoundRenderTargetUniqueID.makeInvalid(); 474 fHWSRGBFramebuffer = kUnknown_TriState; 475 } 476 477 if (resetBits & kPathRendering_GrGLBackendState) { 478 if (this->caps()->shaderCaps()->pathRenderingSupport()) { 479 this->glPathRendering()->resetContext(); 480 } 481 } 482 483 // we assume these values 484 if (resetBits & kPixelStore_GrGLBackendState) { 485 if (this->glCaps().unpackRowLengthSupport()) { 486 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 487 } 488 if (this->glCaps().packRowLengthSupport()) { 489 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 490 } 491 if (this->glCaps().unpackFlipYSupport()) { 492 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 493 } 494 if (this->glCaps().packFlipYSupport()) { 495 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE)); 496 } 497 } 498 499 if (resetBits & kProgram_GrGLBackendState) { 500 fHWProgramID = 0; 501 } 502 } 503 504 static bool check_backend_texture(const GrBackendTexture& backendTex, const GrGLCaps& caps, 505 GrGLTexture::IDDesc* idDesc) { 506 const GrGLTextureInfo* info = backendTex.getGLTextureInfo(); 507 if (!info || !info->fID) { 508 return false; 509 } 510 511 idDesc->fInfo = *info; 512 513 if (GR_GL_TEXTURE_EXTERNAL == idDesc->fInfo.fTarget) { 514 if (!caps.shaderCaps()->externalTextureSupport()) { 515 return false; 516 } 517 } else if (GR_GL_TEXTURE_RECTANGLE == idDesc->fInfo.fTarget) { 518 if (!caps.rectangleTextureSupport()) { 519 return false; 520 } 521 } else if (GR_GL_TEXTURE_2D != idDesc->fInfo.fTarget) { 522 return false; 523 } 524 return true; 525 } 526 527 sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTex, 528 GrWrapOwnership ownership) { 529 GrGLTexture::IDDesc idDesc; 530 if (!check_backend_texture(backendTex, this->glCaps(), &idDesc)) { 531 return nullptr; 532 } 533 if (!idDesc.fInfo.fFormat) { 534 idDesc.fInfo.fFormat = this->glCaps().configSizedInternalFormat(backendTex.config()); 535 } 536 if (kBorrow_GrWrapOwnership == ownership) { 537 idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed; 538 } else { 539 idDesc.fOwnership = GrBackendObjectOwnership::kOwned; 540 } 541 542 GrSurfaceDesc surfDesc; 543 surfDesc.fFlags = kNone_GrSurfaceFlags; 544 surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // This isn't used in the following 545 surfDesc.fWidth = backendTex.width(); 546 surfDesc.fHeight = backendTex.height(); 547 surfDesc.fConfig = backendTex.config(); 548 surfDesc.fSampleCnt = 1; 549 550 GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid 551 : GrMipMapsStatus::kNotAllocated; 552 553 return GrGLTexture::MakeWrapped(this, surfDesc, mipMapsStatus, idDesc); 554 } 555 556 sk_sp<GrTexture> GrGLGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex, 557 int sampleCnt, 558 GrWrapOwnership ownership) { 559 GrGLTexture::IDDesc idDesc; 560 if (!check_backend_texture(backendTex, this->glCaps(), &idDesc)) { 561 return nullptr; 562 } 563 if (!idDesc.fInfo.fFormat) { 564 idDesc.fInfo.fFormat = this->glCaps().configSizedInternalFormat(backendTex.config()); 565 } 566 567 // We don't support rendering to a EXTERNAL texture. 568 if (GR_GL_TEXTURE_EXTERNAL == idDesc.fInfo.fTarget) { 569 return nullptr; 570 } 571 572 if (kBorrow_GrWrapOwnership == ownership) { 573 idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed; 574 } else { 575 idDesc.fOwnership = GrBackendObjectOwnership::kOwned; 576 } 577 578 GrSurfaceDesc surfDesc; 579 surfDesc.fFlags = kRenderTarget_GrSurfaceFlag; 580 surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; // This isn't actually used in the following 581 surfDesc.fWidth = backendTex.width(); 582 surfDesc.fHeight = backendTex.height(); 583 surfDesc.fConfig = backendTex.config(); 584 surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config()); 585 if (surfDesc.fSampleCnt < 1) { 586 return nullptr; 587 } 588 589 GrGLRenderTarget::IDDesc rtIDDesc; 590 if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) { 591 return nullptr; 592 } 593 594 GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kDirty 595 : GrMipMapsStatus::kNotAllocated; 596 597 sk_sp<GrGLTextureRenderTarget> texRT( 598 GrGLTextureRenderTarget::MakeWrapped(this, surfDesc, idDesc, rtIDDesc, mipMapsStatus)); 599 texRT->baseLevelWasBoundToFBO(); 600 return std::move(texRT); 601 } 602 603 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT) { 604 const GrGLFramebufferInfo* info = backendRT.getGLFramebufferInfo(); 605 if (!info) { 606 return nullptr; 607 } 608 609 GrGLRenderTarget::IDDesc idDesc; 610 idDesc.fRTFBOID = info->fFBOID; 611 idDesc.fMSColorRenderbufferID = 0; 612 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 613 idDesc.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed; 614 idDesc.fIsMixedSampled = false; 615 616 GrSurfaceDesc desc; 617 desc.fFlags = kRenderTarget_GrSurfaceFlag; 618 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; // This isn't actually used in the following 619 desc.fWidth = backendRT.width(); 620 desc.fHeight = backendRT.height(); 621 desc.fConfig = backendRT.config(); 622 desc.fSampleCnt = 623 this->caps()->getRenderTargetSampleCount(backendRT.sampleCnt(), backendRT.config()); 624 625 return GrGLRenderTarget::MakeWrapped(this, desc, idDesc, backendRT.stencilBits()); 626 } 627 628 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex, 629 int sampleCnt) { 630 const GrGLTextureInfo* info = tex.getGLTextureInfo(); 631 if (!info || !info->fID) { 632 return nullptr; 633 } 634 635 GrGLTextureInfo texInfo; 636 texInfo = *info; 637 638 if (GR_GL_TEXTURE_RECTANGLE != texInfo.fTarget && 639 GR_GL_TEXTURE_2D != texInfo.fTarget) { 640 // Only texture rectangle and texture 2d are supported. We do not check whether texture 641 // rectangle is supported by Skia - if the caller provided us with a texture rectangle, 642 // we assume the necessary support exists. 643 return nullptr; 644 } 645 646 GrSurfaceDesc surfDesc; 647 surfDesc.fFlags = kRenderTarget_GrSurfaceFlag; 648 surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; // This isn't actually used in the following 649 surfDesc.fWidth = tex.width(); 650 surfDesc.fHeight = tex.height(); 651 surfDesc.fConfig = tex.config(); 652 surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config()); 653 654 GrGLRenderTarget::IDDesc rtIDDesc; 655 if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) { 656 return nullptr; 657 } 658 return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0); 659 } 660 661 //////////////////////////////////////////////////////////////////////////////// 662 663 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width, 664 int height, GrColorType srcColorType, 665 DrawPreference* drawPreference, 666 WritePixelTempDrawInfo* tempDrawInfo) { 667 // We don't want to introduce a sRGB conversion if we trigger a draw. 668 auto srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(dstSurface->config()); 669 if (*drawPreference != kNoDraw_DrawPreference) { 670 // We assume the base class has only inserted a draw for sRGB reasons. So the temp surface 671 // has the config of the original src data. There is no swizzling nor src config spoofing. 672 SkASSERT(tempDrawInfo->fWriteColorType == srcColorType); 673 SkASSERT(GrPixelConfigToColorType(tempDrawInfo->fTempSurfaceDesc.fConfig) == srcColorType); 674 SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA()); 675 // Don't undo a sRGB conversion introduced by our caller via an intermediate draw. 676 srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(tempDrawInfo->fTempSurfaceDesc.fConfig); 677 } 678 if (GrColorTypeIsAlphaOnly(srcColorType)) { 679 srcConfigSRGBEncoded = GrSRGBEncoded::kNo; 680 } 681 682 if (SkToBool(dstSurface->asRenderTarget())) { 683 if (this->glCaps().useDrawInsteadOfAllRenderTargetWrites()) { 684 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 685 } 686 } 687 688 GrGLTexture* texture = static_cast<GrGLTexture*>(dstSurface->asTexture()); 689 690 if (texture) { 691 if (GR_GL_TEXTURE_EXTERNAL == texture->target()) { 692 // We don't currently support writing pixels to EXTERNAL textures. 693 return false; 694 } 695 if (GrPixelConfigIsUnorm(texture->config()) && texture->hasBaseLevelBeenBoundToFBO() && 696 this->glCaps().disallowTexSubImageForUnormConfigTexturesEverBoundToFBO() && 697 (width < dstSurface->width() || height < dstSurface->height())) { 698 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 699 } 700 } else { 701 // This subclass only allows writes to textures. If the dst is not a texture we have to draw 702 // into it. We could use glDrawPixels on GLs that have it, but we don't today. 703 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 704 } 705 706 // If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target. 707 if (dstSurface->asRenderTarget() && dstSurface->asRenderTarget()->numColorSamples() > 1) { 708 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 709 } 710 711 auto srcAsConfig = GrColorTypeToPixelConfig(srcColorType, srcConfigSRGBEncoded); 712 SkASSERT(srcAsConfig != kUnknown_GrPixelConfig); 713 auto dstColorType = GrPixelConfigToColorType(dstSurface->config()); 714 bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcAsConfig) == dstSurface->config(); 715 716 if (configsAreRBSwaps) { 717 if (!this->caps()->isConfigTexturable(srcAsConfig)) { 718 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 719 tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 720 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 721 tempDrawInfo->fWriteColorType = dstColorType; 722 } else if (this->glCaps().rgba8888PixelsOpsAreSlow() && 723 kRGBA_8888_GrPixelConfig == srcAsConfig) { 724 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 725 tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 726 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 727 tempDrawInfo->fWriteColorType = dstColorType; 728 } else if (kGLES_GrGLStandard == this->glStandard() && 729 this->glCaps().bgraIsInternalFormat()) { 730 // The internal format and external formats must match texture uploads so we can't 731 // swizzle while uploading when BGRA is a distinct internal format. 732 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 733 tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 734 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 735 tempDrawInfo->fWriteColorType = dstColorType; 736 } 737 } 738 739 if (!this->glCaps().unpackFlipYSupport() && kBottomLeft_GrSurfaceOrigin == dstOrigin) { 740 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 741 } 742 743 return true; 744 } 745 746 static bool check_write_and_transfer_input(GrGLTexture* glTex) { 747 if (!glTex) { 748 return false; 749 } 750 751 // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textures 752 if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) { 753 return false; 754 } 755 756 return true; 757 } 758 759 bool GrGLGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top, 760 int width, int height, GrColorType srcColorType, 761 const GrMipLevel texels[], int mipLevelCount) { 762 auto glTex = static_cast<GrGLTexture*>(surface->asTexture()); 763 764 if (!check_write_and_transfer_input(glTex)) { 765 return false; 766 } 767 768 this->setScratchTextureUnit(); 769 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 770 771 // No sRGB transformation occurs in uploadTexData. We choose to make the src config match the 772 // srgb-ness of the surface to avoid issues in ES2 where internal/external formats must match. 773 // When we're on ES2 and the dst is GL_SRGB_ALPHA by making the config be kSRGB_8888 we know 774 // that our caps will choose GL_SRGB_ALPHA as the external format, too. On ES3 or regular GL our 775 // caps knows to make the external format be GL_RGBA. 776 auto srgbEncoded = GrPixelConfigIsSRGBEncoded(surface->config()); 777 auto srcAsConfig = GrColorTypeToPixelConfig(srcColorType, srgbEncoded); 778 return this->uploadTexData(glTex->config(), glTex->width(), glTex->height(), origin, 779 glTex->target(), kWrite_UploadType, left, top, width, height, 780 srcAsConfig, texels, mipLevelCount); 781 } 782 783 // For GL_[UN]PACK_ALIGNMENT. 784 static inline GrGLint config_alignment(GrPixelConfig config) { 785 switch (config) { 786 case kAlpha_8_GrPixelConfig: 787 case kAlpha_8_as_Alpha_GrPixelConfig: 788 case kAlpha_8_as_Red_GrPixelConfig: 789 case kGray_8_GrPixelConfig: 790 case kGray_8_as_Lum_GrPixelConfig: 791 case kGray_8_as_Red_GrPixelConfig: 792 return 1; 793 case kRGB_565_GrPixelConfig: 794 case kRGBA_4444_GrPixelConfig: 795 case kAlpha_half_GrPixelConfig: 796 case kAlpha_half_as_Red_GrPixelConfig: 797 case kRGBA_half_GrPixelConfig: 798 return 2; 799 case kRGBA_8888_GrPixelConfig: 800 case kBGRA_8888_GrPixelConfig: 801 case kSRGBA_8888_GrPixelConfig: 802 case kSBGRA_8888_GrPixelConfig: 803 case kRGBA_1010102_GrPixelConfig: 804 case kRGBA_float_GrPixelConfig: 805 case kRG_float_GrPixelConfig: 806 return 4; 807 case kUnknown_GrPixelConfig: 808 return 0; 809 } 810 SK_ABORT("Invalid pixel config"); 811 return 0; 812 } 813 814 bool GrGLGpu::onTransferPixels(GrTexture* texture, int left, int top, int width, int height, 815 GrColorType bufferColorType, GrBuffer* transferBuffer, size_t offset, 816 size_t rowBytes) { 817 GrGLTexture* glTex = static_cast<GrGLTexture*>(texture); 818 GrPixelConfig texConfig = glTex->config(); 819 SkASSERT(this->caps()->isConfigTexturable(texConfig)); 820 821 if (!check_write_and_transfer_input(glTex)) { 822 return false; 823 } 824 825 if (width <= 0 || width > SK_MaxS32 || height <= 0 || height > SK_MaxS32) { 826 return false; 827 } 828 829 this->setScratchTextureUnit(); 830 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 831 832 SkASSERT(!transferBuffer->isMapped()); 833 SkASSERT(!transferBuffer->isCPUBacked()); 834 const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer); 835 this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer); 836 837 SkDEBUGCODE( 838 SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height); 839 SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height()); 840 SkASSERT(bounds.contains(subRect)); 841 ) 842 843 int bpp = GrColorTypeBytesPerPixel(bufferColorType); 844 const size_t trimRowBytes = width * bpp; 845 if (!rowBytes) { 846 rowBytes = trimRowBytes; 847 } 848 const void* pixels = (void*)offset; 849 if (width < 0 || height < 0) { 850 return false; 851 } 852 853 bool restoreGLRowLength = false; 854 if (trimRowBytes != rowBytes) { 855 // we should have checked for this support already 856 SkASSERT(this->glCaps().unpackRowLengthSupport()); 857 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowBytes / bpp)); 858 restoreGLRowLength = true; 859 } 860 861 // Internal format comes from the texture desc. 862 GrGLenum internalFormat; 863 // External format and type come from the upload data. 864 GrGLenum externalFormat; 865 GrGLenum externalType; 866 auto bufferAsConfig = GrColorTypeToPixelConfig(bufferColorType, GrSRGBEncoded::kNo); 867 if (!this->glCaps().getTexImageFormats(texConfig, bufferAsConfig, &internalFormat, 868 &externalFormat, &externalType)) { 869 return false; 870 } 871 872 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(texConfig))); 873 GL_CALL(TexSubImage2D(glTex->target(), 874 0, 875 left, top, 876 width, 877 height, 878 externalFormat, externalType, 879 pixels)); 880 881 if (restoreGLRowLength) { 882 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 883 } 884 885 return true; 886 } 887 888 /** 889 * Creates storage space for the texture and fills it with texels. 890 * 891 * @param config Pixel config of the texture. 892 * @param interface The GL interface in use. 893 * @param caps The capabilities of the GL device. 894 * @param internalFormat The data format used for the internal storage of the texture. May be sized. 895 * @param internalFormatForTexStorage The data format used for the TexStorage API. Must be sized. 896 * @param externalFormat The data format used for the external storage of the texture. 897 * @param externalType The type of the data used for the external storage of the texture. 898 * @param texels The texel data of the texture being created. 899 * @param baseWidth The width of the texture's base mipmap level 900 * @param baseHeight The height of the texture's base mipmap level 901 */ 902 static bool allocate_and_populate_texture(GrPixelConfig config, 903 const GrGLInterface& interface, 904 const GrGLCaps& caps, 905 GrGLenum target, 906 GrGLenum internalFormat, 907 GrGLenum internalFormatForTexStorage, 908 GrGLenum externalFormat, 909 GrGLenum externalType, 910 const GrMipLevel texels[], int mipLevelCount, 911 int baseWidth, int baseHeight) { 912 CLEAR_ERROR_BEFORE_ALLOC(&interface); 913 914 bool useTexStorage = caps.isConfigTexSupportEnabled(config); 915 // We can only use TexStorage if we know we will not later change the storage requirements. 916 // This means if we may later want to add mipmaps, we cannot use TexStorage. 917 // Right now, we cannot know if we will later add mipmaps or not. 918 // The only time we can use TexStorage is when we already have the 919 // mipmaps. 920 useTexStorage &= mipLevelCount > 1; 921 922 if (useTexStorage) { 923 // We never resize or change formats of textures. 924 GL_ALLOC_CALL(&interface, 925 TexStorage2D(target, SkTMax(mipLevelCount, 1), internalFormatForTexStorage, 926 baseWidth, baseHeight)); 927 GrGLenum error = CHECK_ALLOC_ERROR(&interface); 928 if (error != GR_GL_NO_ERROR) { 929 return false; 930 } else { 931 for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) { 932 const void* currentMipData = texels[currentMipLevel].fPixels; 933 if (currentMipData == nullptr) { 934 continue; 935 } 936 int twoToTheMipLevel = 1 << currentMipLevel; 937 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); 938 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); 939 940 GR_GL_CALL(&interface, 941 TexSubImage2D(target, 942 currentMipLevel, 943 0, // left 944 0, // top 945 currentWidth, 946 currentHeight, 947 externalFormat, externalType, 948 currentMipData)); 949 } 950 return true; 951 } 952 } else { 953 if (!mipLevelCount) { 954 GL_ALLOC_CALL(&interface, 955 TexImage2D(target, 956 0, 957 internalFormat, 958 baseWidth, 959 baseHeight, 960 0, // border 961 externalFormat, externalType, 962 nullptr)); 963 GrGLenum error = CHECK_ALLOC_ERROR(&interface); 964 if (error != GR_GL_NO_ERROR) { 965 return false; 966 } 967 } else { 968 for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) { 969 int twoToTheMipLevel = 1 << currentMipLevel; 970 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); 971 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); 972 const void* currentMipData = texels[currentMipLevel].fPixels; 973 // Even if curremtMipData is nullptr, continue to call TexImage2D. 974 // This will allocate texture memory which we can later populate. 975 GL_ALLOC_CALL(&interface, 976 TexImage2D(target, 977 currentMipLevel, 978 internalFormat, 979 currentWidth, 980 currentHeight, 981 0, // border 982 externalFormat, externalType, 983 currentMipData)); 984 GrGLenum error = CHECK_ALLOC_ERROR(&interface); 985 if (error != GR_GL_NO_ERROR) { 986 return false; 987 } 988 } 989 } 990 } 991 return true; 992 } 993 994 /** 995 * After a texture is created, any state which was altered during its creation 996 * needs to be restored. 997 * 998 * @param interface The GL interface to use. 999 * @param caps The capabilities of the GL device. 1000 * @param restoreGLRowLength Should the row length unpacking be restored? 1001 * @param glFlipY Did GL flip the texture vertically? 1002 */ 1003 static void restore_pixelstore_state(const GrGLInterface& interface, const GrGLCaps& caps, 1004 bool restoreGLRowLength, bool glFlipY) { 1005 if (restoreGLRowLength) { 1006 SkASSERT(caps.unpackRowLengthSupport()); 1007 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 1008 } 1009 if (glFlipY) { 1010 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 1011 } 1012 } 1013 1014 void GrGLGpu::unbindCpuToGpuXferBuffer() { 1015 auto& xferBufferState = fHWBufferState[kXferCpuToGpu_GrBufferType]; 1016 if (!xferBufferState.fBoundBufferUniqueID.isInvalid()) { 1017 GL_CALL(BindBuffer(xferBufferState.fGLTarget, 0)); 1018 xferBufferState.invalidate(); 1019 } 1020 1021 } 1022 1023 // TODO: Make this take a GrColorType instead of dataConfig. This requires updating GrGLCaps to 1024 // convert from GrColorType to externalFormat/externalType GLenum values. 1025 bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight, 1026 GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType, 1027 int left, int top, int width, int height, GrPixelConfig dataConfig, 1028 const GrMipLevel texels[], int mipLevelCount, 1029 GrMipMapsStatus* mipMapsStatus) { 1030 SkASSERT(this->caps()->isConfigTexturable(texConfig)); 1031 SkDEBUGCODE( 1032 SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height); 1033 SkIRect bounds = SkIRect::MakeWH(texWidth, texHeight); 1034 SkASSERT(bounds.contains(subRect)); 1035 ) 1036 SkASSERT(1 == mipLevelCount || 1037 (0 == left && 0 == top && width == texWidth && height == texHeight)); 1038 1039 this->unbindCpuToGpuXferBuffer(); 1040 1041 // texels is const. 1042 // But we may need to flip the texture vertically to prepare it. 1043 // Rather than flip in place and alter the incoming data, 1044 // we allocate a new buffer to flip into. 1045 // This means we need to make a non-const shallow copy of texels. 1046 SkAutoTMalloc<GrMipLevel> texelsShallowCopy; 1047 1048 if (mipLevelCount) { 1049 texelsShallowCopy.reset(mipLevelCount); 1050 memcpy(texelsShallowCopy.get(), texels, mipLevelCount*sizeof(GrMipLevel)); 1051 } 1052 1053 const GrGLInterface* interface = this->glInterface(); 1054 const GrGLCaps& caps = this->glCaps(); 1055 1056 size_t bpp = GrBytesPerPixel(dataConfig); 1057 1058 if (width == 0 || height == 0) { 1059 return false; 1060 } 1061 1062 // Internal format comes from the texture desc. 1063 GrGLenum internalFormat; 1064 // External format and type come from the upload data. 1065 GrGLenum externalFormat; 1066 GrGLenum externalType; 1067 if (!this->glCaps().getTexImageFormats(texConfig, dataConfig, &internalFormat, &externalFormat, 1068 &externalType)) { 1069 return false; 1070 } 1071 // TexStorage requires a sized format, and internalFormat may or may not be 1072 GrGLenum internalFormatForTexStorage = this->glCaps().configSizedInternalFormat(texConfig); 1073 1074 /* 1075 * Check whether to allocate a temporary buffer for flipping y or 1076 * because our srcData has extra bytes past each row. If so, we need 1077 * to trim those off here, since GL ES may not let us specify 1078 * GL_UNPACK_ROW_LENGTH. 1079 */ 1080 bool restoreGLRowLength = false; 1081 bool swFlipY = false; 1082 bool glFlipY = false; 1083 1084 if (kBottomLeft_GrSurfaceOrigin == texOrigin && mipLevelCount) { 1085 if (caps.unpackFlipYSupport()) { 1086 glFlipY = true; 1087 } else { 1088 swFlipY = true; 1089 } 1090 } 1091 1092 // in case we need a temporary, trimmed copy of the src pixels 1093 SkAutoSMalloc<128 * 128> tempStorage; 1094 1095 if (mipMapsStatus) { 1096 *mipMapsStatus = GrMipMapsStatus::kValid; 1097 } 1098 1099 const bool usesMips = mipLevelCount > 1; 1100 1101 // find the combined size of all the mip levels and the relative offset of 1102 // each into the collective buffer 1103 bool willNeedData = false; 1104 size_t combinedBufferSize = 0; 1105 SkTArray<size_t> individualMipOffsets(mipLevelCount); 1106 for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) { 1107 if (texelsShallowCopy[currentMipLevel].fPixels) { 1108 int twoToTheMipLevel = 1 << currentMipLevel; 1109 int currentWidth = SkTMax(1, width / twoToTheMipLevel); 1110 int currentHeight = SkTMax(1, height / twoToTheMipLevel); 1111 const size_t trimRowBytes = currentWidth * bpp; 1112 const size_t trimmedSize = trimRowBytes * currentHeight; 1113 1114 const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes 1115 ? texelsShallowCopy[currentMipLevel].fRowBytes 1116 : trimRowBytes; 1117 1118 1119 if (((!caps.unpackRowLengthSupport() || usesMips) && trimRowBytes != rowBytes) || 1120 swFlipY) { 1121 willNeedData = true; 1122 } 1123 1124 individualMipOffsets.push_back(combinedBufferSize); 1125 combinedBufferSize += trimmedSize; 1126 } else { 1127 if (mipMapsStatus) { 1128 *mipMapsStatus = GrMipMapsStatus::kDirty; 1129 } 1130 individualMipOffsets.push_back(0); 1131 } 1132 } 1133 if (mipMapsStatus && mipLevelCount <= 1) { 1134 *mipMapsStatus = GrMipMapsStatus::kNotAllocated; 1135 } 1136 char* buffer = nullptr; 1137 if (willNeedData) { 1138 buffer = (char*)tempStorage.reset(combinedBufferSize); 1139 } 1140 1141 for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) { 1142 if (!texelsShallowCopy[currentMipLevel].fPixels) { 1143 continue; 1144 } 1145 int twoToTheMipLevel = 1 << currentMipLevel; 1146 int currentWidth = SkTMax(1, width / twoToTheMipLevel); 1147 int currentHeight = SkTMax(1, height / twoToTheMipLevel); 1148 const size_t trimRowBytes = currentWidth * bpp; 1149 1150 /* 1151 * check whether to allocate a temporary buffer for flipping y or 1152 * because our srcData has extra bytes past each row. If so, we need 1153 * to trim those off here, since GL ES may not let us specify 1154 * GL_UNPACK_ROW_LENGTH. 1155 */ 1156 restoreGLRowLength = false; 1157 1158 const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes 1159 ? texelsShallowCopy[currentMipLevel].fRowBytes 1160 : trimRowBytes; 1161 1162 // TODO: This optimization should be enabled with or without mips. 1163 // For use with mips, we must set GR_GL_UNPACK_ROW_LENGTH once per 1164 // mip level, before calling glTexImage2D. 1165 if (caps.unpackRowLengthSupport() && !swFlipY && !usesMips) { 1166 // can't use this for flipping, only non-neg values allowed. :( 1167 if (rowBytes != trimRowBytes) { 1168 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); 1169 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); 1170 restoreGLRowLength = true; 1171 } 1172 } else if (trimRowBytes != rowBytes || swFlipY) { 1173 // copy data into our new storage, skipping the trailing bytes 1174 const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels; 1175 if (swFlipY && currentHeight >= 1) { 1176 src += (currentHeight - 1) * rowBytes; 1177 } 1178 char* dst = buffer + individualMipOffsets[currentMipLevel]; 1179 for (int y = 0; y < currentHeight; y++) { 1180 memcpy(dst, src, trimRowBytes); 1181 if (swFlipY) { 1182 src -= rowBytes; 1183 } else { 1184 src += rowBytes; 1185 } 1186 dst += trimRowBytes; 1187 } 1188 // now point data to our copied version 1189 texelsShallowCopy[currentMipLevel].fPixels = buffer + 1190 individualMipOffsets[currentMipLevel]; 1191 texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes; 1192 } 1193 } 1194 1195 if (mipLevelCount) { 1196 if (glFlipY) { 1197 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); 1198 } 1199 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(texConfig))); 1200 } 1201 1202 bool succeeded = true; 1203 if (kNewTexture_UploadType == uploadType) { 1204 if (0 == left && 0 == top && texWidth == width && texHeight == height) { 1205 succeeded = allocate_and_populate_texture( 1206 texConfig, *interface, caps, target, internalFormat, 1207 internalFormatForTexStorage, externalFormat, externalType, 1208 texelsShallowCopy, mipLevelCount, width, height); 1209 } else { 1210 succeeded = false; 1211 } 1212 } else { 1213 if (swFlipY || glFlipY) { 1214 top = texHeight - (top + height); 1215 } 1216 for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) { 1217 if (!texelsShallowCopy[currentMipLevel].fPixels) { 1218 continue; 1219 } 1220 int twoToTheMipLevel = 1 << currentMipLevel; 1221 int currentWidth = SkTMax(1, width / twoToTheMipLevel); 1222 int currentHeight = SkTMax(1, height / twoToTheMipLevel); 1223 1224 GL_CALL(TexSubImage2D(target, 1225 currentMipLevel, 1226 left, top, 1227 currentWidth, 1228 currentHeight, 1229 externalFormat, externalType, 1230 texelsShallowCopy[currentMipLevel].fPixels)); 1231 } 1232 } 1233 1234 restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY); 1235 1236 return succeeded; 1237 } 1238 1239 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, 1240 int sampleCount, 1241 GrGLenum format, 1242 int width, int height) { 1243 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); 1244 SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType()); 1245 switch (ctx.caps()->msFBOType()) { 1246 case GrGLCaps::kStandard_MSFBOType: 1247 case GrGLCaps::kMixedSamples_MSFBOType: 1248 GL_ALLOC_CALL(ctx.interface(), 1249 RenderbufferStorageMultisample(GR_GL_RENDERBUFFER, 1250 sampleCount, 1251 format, 1252 width, height)); 1253 break; 1254 case GrGLCaps::kES_Apple_MSFBOType: 1255 GL_ALLOC_CALL(ctx.interface(), 1256 RenderbufferStorageMultisampleES2APPLE(GR_GL_RENDERBUFFER, 1257 sampleCount, 1258 format, 1259 width, height)); 1260 break; 1261 case GrGLCaps::kES_EXT_MsToTexture_MSFBOType: 1262 case GrGLCaps::kES_IMG_MsToTexture_MSFBOType: 1263 GL_ALLOC_CALL(ctx.interface(), 1264 RenderbufferStorageMultisampleES2EXT(GR_GL_RENDERBUFFER, 1265 sampleCount, 1266 format, 1267 width, height)); 1268 break; 1269 case GrGLCaps::kNone_MSFBOType: 1270 SK_ABORT("Shouldn't be here if we don't support multisampled renderbuffers."); 1271 break; 1272 } 1273 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface())); 1274 } 1275 1276 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, 1277 const GrGLTextureInfo& texInfo, 1278 GrGLRenderTarget::IDDesc* idDesc) { 1279 idDesc->fMSColorRenderbufferID = 0; 1280 idDesc->fRTFBOID = 0; 1281 idDesc->fRTFBOOwnership = GrBackendObjectOwnership::kOwned; 1282 idDesc->fTexFBOID = 0; 1283 SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) == 1284 this->caps()->usesMixedSamples()); 1285 idDesc->fIsMixedSampled = desc.fSampleCnt > 1 && this->caps()->usesMixedSamples(); 1286 1287 GrGLenum status; 1288 1289 GrGLenum colorRenderbufferFormat = 0; // suppress warning 1290 1291 if (desc.fSampleCnt > 1 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) { 1292 goto FAILED; 1293 } 1294 1295 GL_CALL(GenFramebuffers(1, &idDesc->fTexFBOID)); 1296 if (!idDesc->fTexFBOID) { 1297 goto FAILED; 1298 } 1299 1300 // If we are using multisampling we will create two FBOS. We render to one and then resolve to 1301 // the texture bound to the other. The exception is the IMG multisample extension. With this 1302 // extension the texture is multisampled when rendered to and then auto-resolves it when it is 1303 // rendered from. 1304 if (desc.fSampleCnt > 1 && this->glCaps().usesMSAARenderBuffers()) { 1305 GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID)); 1306 GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); 1307 if (!idDesc->fRTFBOID || 1308 !idDesc->fMSColorRenderbufferID) { 1309 goto FAILED; 1310 } 1311 if (!this->glCaps().getRenderbufferFormat(desc.fConfig, &colorRenderbufferFormat)) { 1312 return false; 1313 } 1314 } else { 1315 idDesc->fRTFBOID = idDesc->fTexFBOID; 1316 } 1317 1318 // below here we may bind the FBO 1319 fHWBoundRenderTargetUniqueID.makeInvalid(); 1320 if (idDesc->fRTFBOID != idDesc->fTexFBOID) { 1321 SkASSERT(desc.fSampleCnt > 1); 1322 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbufferID)); 1323 if (!renderbuffer_storage_msaa(*fGLContext, 1324 desc.fSampleCnt, 1325 colorRenderbufferFormat, 1326 desc.fWidth, desc.fHeight)) { 1327 goto FAILED; 1328 } 1329 fStats.incRenderTargetBinds(); 1330 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); 1331 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1332 GR_GL_COLOR_ATTACHMENT0, 1333 GR_GL_RENDERBUFFER, 1334 idDesc->fMSColorRenderbufferID)); 1335 if (!this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { 1336 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1337 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1338 goto FAILED; 1339 } 1340 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); 1341 } 1342 } 1343 fStats.incRenderTargetBinds(); 1344 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID)); 1345 1346 if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 1) { 1347 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, 1348 GR_GL_COLOR_ATTACHMENT0, 1349 texInfo.fTarget, 1350 texInfo.fID, 0, desc.fSampleCnt)); 1351 } else { 1352 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, 1353 GR_GL_COLOR_ATTACHMENT0, 1354 texInfo.fTarget, 1355 texInfo.fID, 0)); 1356 } 1357 if (!this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { 1358 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1359 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1360 goto FAILED; 1361 } 1362 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); 1363 } 1364 1365 return true; 1366 1367 FAILED: 1368 if (idDesc->fMSColorRenderbufferID) { 1369 GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); 1370 } 1371 if (idDesc->fRTFBOID != idDesc->fTexFBOID) { 1372 GL_CALL(DeleteFramebuffers(1, &idDesc->fRTFBOID)); 1373 } 1374 if (idDesc->fTexFBOID) { 1375 GL_CALL(DeleteFramebuffers(1, &idDesc->fTexFBOID)); 1376 } 1377 return false; 1378 } 1379 1380 // good to set a break-point here to know when createTexture fails 1381 static sk_sp<GrTexture> return_null_texture() { 1382 // SkDEBUGFAIL("null texture"); 1383 return nullptr; 1384 } 1385 1386 #if 0 && defined(SK_DEBUG) 1387 static size_t as_size_t(int x) { 1388 return x; 1389 } 1390 #endif 1391 1392 static void set_initial_texture_params(const GrGLInterface* interface, 1393 const GrGLTextureInfo& info, 1394 GrGLTexture::TexParams* initialTexParams) { 1395 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1396 // drivers have a bug where an FBO won't be complete if it includes a 1397 // texture that is not mipmap complete (considering the filter in use). 1398 // we only set a subset here so invalidate first 1399 initialTexParams->invalidate(); 1400 initialTexParams->fMinFilter = GR_GL_NEAREST; 1401 initialTexParams->fMagFilter = GR_GL_NEAREST; 1402 initialTexParams->fWrapS = GR_GL_CLAMP_TO_EDGE; 1403 initialTexParams->fWrapT = GR_GL_CLAMP_TO_EDGE; 1404 GR_GL_CALL(interface, TexParameteri(info.fTarget, 1405 GR_GL_TEXTURE_MAG_FILTER, 1406 initialTexParams->fMagFilter)); 1407 GR_GL_CALL(interface, TexParameteri(info.fTarget, 1408 GR_GL_TEXTURE_MIN_FILTER, 1409 initialTexParams->fMinFilter)); 1410 GR_GL_CALL(interface, TexParameteri(info.fTarget, 1411 GR_GL_TEXTURE_WRAP_S, 1412 initialTexParams->fWrapS)); 1413 GR_GL_CALL(interface, TexParameteri(info.fTarget, 1414 GR_GL_TEXTURE_WRAP_T, 1415 initialTexParams->fWrapT)); 1416 } 1417 1418 sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, 1419 SkBudgeted budgeted, 1420 const GrMipLevel texels[], 1421 int mipLevelCount) { 1422 // We fail if the MSAA was requested and is not available. 1423 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt > 1) { 1424 //SkDebugf("MSAA RT requested but not supported on this platform."); 1425 return return_null_texture(); 1426 } 1427 1428 bool performClear = (desc.fFlags & kPerformInitialClear_GrSurfaceFlag); 1429 1430 GrMipLevel zeroLevel; 1431 std::unique_ptr<uint8_t[]> zeros; 1432 if (performClear && !this->glCaps().clearTextureSupport() && 1433 !this->glCaps().canConfigBeFBOColorAttachment(desc.fConfig)) { 1434 size_t rowSize = GrBytesPerPixel(desc.fConfig) * desc.fWidth; 1435 size_t size = rowSize * desc.fHeight; 1436 zeros.reset(new uint8_t[size]); 1437 memset(zeros.get(), 0, size); 1438 zeroLevel.fPixels = zeros.get(); 1439 zeroLevel.fRowBytes = 0; 1440 texels = &zeroLevel; 1441 mipLevelCount = 1; 1442 performClear = false; 1443 } 1444 1445 bool isRenderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 1446 1447 GrGLTexture::IDDesc idDesc; 1448 idDesc.fOwnership = GrBackendObjectOwnership::kOwned; 1449 GrMipMapsStatus mipMapsStatus; 1450 GrGLTexture::TexParams initialTexParams; 1451 if (!this->createTextureImpl(desc, &idDesc.fInfo, isRenderTarget, &initialTexParams, 1452 texels, mipLevelCount, &mipMapsStatus)) { 1453 return return_null_texture(); 1454 } 1455 1456 sk_sp<GrGLTexture> tex; 1457 if (isRenderTarget) { 1458 // unbind the texture from the texture unit before binding it to the frame buffer 1459 GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0)); 1460 GrGLRenderTarget::IDDesc rtIDDesc; 1461 1462 if (!this->createRenderTargetObjects(desc, idDesc.fInfo, &rtIDDesc)) { 1463 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); 1464 return return_null_texture(); 1465 } 1466 tex = sk_make_sp<GrGLTextureRenderTarget>(this, budgeted, desc, idDesc, rtIDDesc, 1467 mipMapsStatus); 1468 tex->baseLevelWasBoundToFBO(); 1469 } else { 1470 tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc, mipMapsStatus); 1471 } 1472 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1473 #ifdef TRACE_TEXTURE_CREATION 1474 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", 1475 idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig); 1476 #endif 1477 if (tex && performClear) { 1478 if (this->glCaps().clearTextureSupport()) { 1479 static constexpr uint32_t kZero = 0; 1480 GL_CALL(ClearTexImage(tex->textureID(), 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, &kZero)); 1481 } else { 1482 GrGLIRect viewport; 1483 this->bindSurfaceFBOForPixelOps(tex.get(), GR_GL_FRAMEBUFFER, &viewport, 1484 kDst_TempFBOTarget); 1485 this->disableScissor(); 1486 this->disableWindowRectangles(); 1487 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 1488 fHWWriteToColor = kYes_TriState; 1489 GL_CALL(ClearColor(0, 0, 0, 0)); 1490 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); 1491 this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, tex.get()); 1492 fHWBoundRenderTargetUniqueID.makeInvalid(); 1493 } 1494 } 1495 return tex; 1496 } 1497 1498 namespace { 1499 1500 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; 1501 1502 void inline get_stencil_rb_sizes(const GrGLInterface* gl, 1503 GrGLStencilAttachment::Format* format) { 1504 1505 // we shouldn't ever know one size and not the other 1506 SkASSERT((kUnknownBitCount == format->fStencilBits) == 1507 (kUnknownBitCount == format->fTotalBits)); 1508 if (kUnknownBitCount == format->fStencilBits) { 1509 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 1510 GR_GL_RENDERBUFFER_STENCIL_SIZE, 1511 (GrGLint*)&format->fStencilBits); 1512 if (format->fPacked) { 1513 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 1514 GR_GL_RENDERBUFFER_DEPTH_SIZE, 1515 (GrGLint*)&format->fTotalBits); 1516 format->fTotalBits += format->fStencilBits; 1517 } else { 1518 format->fTotalBits = format->fStencilBits; 1519 } 1520 } 1521 } 1522 } 1523 1524 int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) { 1525 static const int kSize = 16; 1526 SkASSERT(this->caps()->isConfigRenderable(config)); 1527 if (!this->glCaps().hasStencilFormatBeenDeterminedForConfig(config)) { 1528 // Default to unsupported, set this if we find a stencil format that works. 1529 int firstWorkingStencilFormatIndex = -1; 1530 1531 // Create color texture 1532 GrGLuint colorID = 0; 1533 GL_CALL(GenTextures(1, &colorID)); 1534 this->setScratchTextureUnit(); 1535 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, colorID)); 1536 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1537 GR_GL_TEXTURE_MAG_FILTER, 1538 GR_GL_NEAREST)); 1539 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1540 GR_GL_TEXTURE_MIN_FILTER, 1541 GR_GL_NEAREST)); 1542 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1543 GR_GL_TEXTURE_WRAP_S, 1544 GR_GL_CLAMP_TO_EDGE)); 1545 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1546 GR_GL_TEXTURE_WRAP_T, 1547 GR_GL_CLAMP_TO_EDGE)); 1548 1549 GrGLenum internalFormat; 1550 GrGLenum externalFormat; 1551 GrGLenum externalType; 1552 if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat, 1553 &externalType)) { 1554 return false; 1555 } 1556 this->unbindCpuToGpuXferBuffer(); 1557 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1558 GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, 1559 0, 1560 internalFormat, 1561 kSize, 1562 kSize, 1563 0, 1564 externalFormat, 1565 externalType, 1566 nullptr)); 1567 if (GR_GL_NO_ERROR != CHECK_ALLOC_ERROR(this->glInterface())) { 1568 GL_CALL(DeleteTextures(1, &colorID)); 1569 return -1; 1570 } 1571 1572 // unbind the texture from the texture unit before binding it to the frame buffer 1573 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); 1574 1575 // Create Framebuffer 1576 GrGLuint fb = 0; 1577 GL_CALL(GenFramebuffers(1, &fb)); 1578 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fb)); 1579 fHWBoundRenderTargetUniqueID.makeInvalid(); 1580 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, 1581 GR_GL_COLOR_ATTACHMENT0, 1582 GR_GL_TEXTURE_2D, 1583 colorID, 1584 0)); 1585 GrGLuint sbRBID = 0; 1586 GL_CALL(GenRenderbuffers(1, &sbRBID)); 1587 1588 // look over formats till I find a compatible one 1589 int stencilFmtCnt = this->glCaps().stencilFormats().count(); 1590 if (sbRBID) { 1591 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbRBID)); 1592 for (int i = 0; i < stencilFmtCnt && sbRBID; ++i) { 1593 const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[i]; 1594 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1595 GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER, 1596 sFmt.fInternalFormat, 1597 kSize, kSize)); 1598 if (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface())) { 1599 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1600 GR_GL_STENCIL_ATTACHMENT, 1601 GR_GL_RENDERBUFFER, sbRBID)); 1602 if (sFmt.fPacked) { 1603 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1604 GR_GL_DEPTH_ATTACHMENT, 1605 GR_GL_RENDERBUFFER, sbRBID)); 1606 } else { 1607 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1608 GR_GL_DEPTH_ATTACHMENT, 1609 GR_GL_RENDERBUFFER, 0)); 1610 } 1611 GrGLenum status; 1612 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1613 if (status == GR_GL_FRAMEBUFFER_COMPLETE) { 1614 firstWorkingStencilFormatIndex = i; 1615 break; 1616 } 1617 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1618 GR_GL_STENCIL_ATTACHMENT, 1619 GR_GL_RENDERBUFFER, 0)); 1620 if (sFmt.fPacked) { 1621 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1622 GR_GL_DEPTH_ATTACHMENT, 1623 GR_GL_RENDERBUFFER, 0)); 1624 } 1625 } 1626 } 1627 GL_CALL(DeleteRenderbuffers(1, &sbRBID)); 1628 } 1629 GL_CALL(DeleteTextures(1, &colorID)); 1630 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); 1631 GL_CALL(DeleteFramebuffers(1, &fb)); 1632 fGLContext->caps()->setStencilFormatIndexForConfig(config, firstWorkingStencilFormatIndex); 1633 } 1634 return this->glCaps().getStencilFormatIndexForConfig(config); 1635 } 1636 1637 bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, 1638 bool renderTarget, GrGLTexture::TexParams* initialTexParams, 1639 const GrMipLevel texels[], int mipLevelCount, 1640 GrMipMapsStatus* mipMapsStatus) { 1641 info->fID = 0; 1642 info->fTarget = GR_GL_TEXTURE_2D; 1643 GL_CALL(GenTextures(1, &(info->fID))); 1644 1645 if (!info->fID) { 1646 return false; 1647 } 1648 1649 this->setScratchTextureUnit(); 1650 GL_CALL(BindTexture(info->fTarget, info->fID)); 1651 1652 if (renderTarget && this->glCaps().textureUsageSupport()) { 1653 // provides a hint about how this texture will be used 1654 GL_CALL(TexParameteri(info->fTarget, 1655 GR_GL_TEXTURE_USAGE, 1656 GR_GL_FRAMEBUFFER_ATTACHMENT)); 1657 } 1658 1659 if (info) { 1660 set_initial_texture_params(this->glInterface(), *info, initialTexParams); 1661 } 1662 if (!this->uploadTexData(desc.fConfig, desc.fWidth, desc.fHeight, desc.fOrigin, info->fTarget, 1663 kNewTexture_UploadType, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 1664 texels, mipLevelCount, mipMapsStatus)) { 1665 GL_CALL(DeleteTextures(1, &(info->fID))); 1666 return false; 1667 } 1668 info->fFormat = this->glCaps().configSizedInternalFormat(desc.fConfig); 1669 return true; 1670 } 1671 1672 GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 1673 int width, int height) { 1674 SkASSERT(width >= rt->width()); 1675 SkASSERT(height >= rt->height()); 1676 1677 int samples = rt->numStencilSamples(); 1678 GrGLStencilAttachment::IDDesc sbDesc; 1679 1680 int sIdx = this->getCompatibleStencilIndex(rt->config()); 1681 if (sIdx < 0) { 1682 return nullptr; 1683 } 1684 1685 if (!sbDesc.fRenderbufferID) { 1686 GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID)); 1687 } 1688 if (!sbDesc.fRenderbufferID) { 1689 return nullptr; 1690 } 1691 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); 1692 const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx]; 1693 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1694 // we do this "if" so that we don't call the multisample 1695 // version on a GL that doesn't have an MSAA extension. 1696 if (samples > 1) { 1697 SkAssertResult(renderbuffer_storage_msaa(*fGLContext, 1698 samples, 1699 sFmt.fInternalFormat, 1700 width, height)); 1701 } else { 1702 GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER, 1703 sFmt.fInternalFormat, 1704 width, height)); 1705 SkASSERT(GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface())); 1706 } 1707 fStats.incStencilAttachmentCreates(); 1708 // After sized formats we attempt an unsized format and take 1709 // whatever sizes GL gives us. In that case we query for the size. 1710 GrGLStencilAttachment::Format format = sFmt; 1711 get_stencil_rb_sizes(this->glInterface(), &format); 1712 GrGLStencilAttachment* stencil = new GrGLStencilAttachment(this, 1713 sbDesc, 1714 width, 1715 height, 1716 samples, 1717 format); 1718 return stencil; 1719 } 1720 1721 //////////////////////////////////////////////////////////////////////////////// 1722 1723 // GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer 1724 // objects are implemented as client-side-arrays on tile-deferred architectures. 1725 #define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW 1726 1727 GrBuffer* GrGLGpu::onCreateBuffer(size_t size, GrBufferType intendedType, 1728 GrAccessPattern accessPattern, const void* data) { 1729 return GrGLBuffer::Create(this, size, intendedType, accessPattern, data); 1730 } 1731 1732 void GrGLGpu::flushScissor(const GrScissorState& scissorState, 1733 const GrGLIRect& rtViewport, 1734 GrSurfaceOrigin rtOrigin) { 1735 if (scissorState.enabled()) { 1736 GrGLIRect scissor; 1737 scissor.setRelativeTo(rtViewport, scissorState.rect(), rtOrigin); 1738 // if the scissor fully contains the viewport then we fall through and 1739 // disable the scissor test. 1740 if (!scissor.contains(rtViewport)) { 1741 if (fHWScissorSettings.fRect != scissor) { 1742 scissor.pushToGLScissor(this->glInterface()); 1743 fHWScissorSettings.fRect = scissor; 1744 } 1745 if (kYes_TriState != fHWScissorSettings.fEnabled) { 1746 GL_CALL(Enable(GR_GL_SCISSOR_TEST)); 1747 fHWScissorSettings.fEnabled = kYes_TriState; 1748 } 1749 return; 1750 } 1751 } 1752 1753 // See fall through note above 1754 this->disableScissor(); 1755 } 1756 1757 void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState, 1758 const GrGLRenderTarget* rt, GrSurfaceOrigin origin) { 1759 #ifndef USE_NSIGHT 1760 typedef GrWindowRectsState::Mode Mode; 1761 SkASSERT(!windowState.enabled() || rt->renderFBOID()); // Window rects can't be used on-screen. 1762 SkASSERT(windowState.numWindows() <= this->caps()->maxWindowRectangles()); 1763 1764 if (!this->caps()->maxWindowRectangles() || 1765 fHWWindowRectsState.knownEqualTo(origin, rt->getViewport(), windowState)) { 1766 return; 1767 } 1768 1769 // This is purely a workaround for a spurious warning generated by gcc. Otherwise the above 1770 // assert would be sufficient. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=5912 1771 int numWindows = SkTMin(windowState.numWindows(), int(GrWindowRectangles::kMaxWindows)); 1772 SkASSERT(windowState.numWindows() == numWindows); 1773 1774 GrGLIRect glwindows[GrWindowRectangles::kMaxWindows]; 1775 const SkIRect* skwindows = windowState.windows().data(); 1776 for (int i = 0; i < numWindows; ++i) { 1777 glwindows[i].setRelativeTo(rt->getViewport(), skwindows[i], origin); 1778 } 1779 1780 GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE; 1781 GL_CALL(WindowRectangles(glmode, numWindows, glwindows->asInts())); 1782 1783 fHWWindowRectsState.set(origin, rt->getViewport(), windowState); 1784 #endif 1785 } 1786 1787 void GrGLGpu::disableWindowRectangles() { 1788 #ifndef USE_NSIGHT 1789 if (!this->caps()->maxWindowRectangles() || fHWWindowRectsState.knownDisabled()) { 1790 return; 1791 } 1792 GL_CALL(WindowRectangles(GR_GL_EXCLUSIVE, 0, nullptr)); 1793 fHWWindowRectsState.setDisabled(); 1794 #endif 1795 } 1796 1797 void GrGLGpu::flushMinSampleShading(float minSampleShading) { 1798 if (fHWMinSampleShading != minSampleShading) { 1799 if (minSampleShading > 0.0) { 1800 GL_CALL(Enable(GR_GL_SAMPLE_SHADING)); 1801 GL_CALL(MinSampleShading(minSampleShading)); 1802 } 1803 else { 1804 GL_CALL(Disable(GR_GL_SAMPLE_SHADING)); 1805 } 1806 fHWMinSampleShading = minSampleShading; 1807 } 1808 } 1809 1810 bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc, 1811 bool willDrawPoints) { 1812 sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc, willDrawPoints)); 1813 if (!program) { 1814 GrCapsDebugf(this->caps(), "Failed to create program!\n"); 1815 return false; 1816 } 1817 1818 program->generateMipmaps(primProc, pipeline); 1819 1820 GrXferProcessor::BlendInfo blendInfo; 1821 pipeline.getXferProcessor().getBlendInfo(&blendInfo); 1822 1823 this->flushColorWrite(blendInfo.fWriteColor); 1824 this->flushMinSampleShading(primProc.getSampleShading()); 1825 1826 GrGLuint programID = program->programID(); 1827 if (fHWProgramID != programID) { 1828 GL_CALL(UseProgram(programID)); 1829 fHWProgramID = programID; 1830 } 1831 1832 if (blendInfo.fWriteColor) { 1833 // Swizzle the blend to match what the shader will output. 1834 const GrSwizzle& swizzle = this->caps()->shaderCaps()->configOutputSwizzle( 1835 pipeline.proxy()->config()); 1836 this->flushBlend(blendInfo, swizzle); 1837 } 1838 1839 program->setData(primProc, pipeline); 1840 1841 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget()); 1842 GrStencilSettings stencil; 1843 if (pipeline.isStencilEnabled()) { 1844 // TODO: attach stencil and create settings during render target flush. 1845 SkASSERT(glRT->renderTargetPriv().getStencilAttachment()); 1846 stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), 1847 glRT->renderTargetPriv().numStencilBits()); 1848 } 1849 this->flushStencil(stencil); 1850 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), pipeline.proxy()->origin()); 1851 this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, pipeline.proxy()->origin()); 1852 this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled()); 1853 1854 // This must come after textures are flushed because a texture may need 1855 // to be msaa-resolved (which will modify bound FBO state). 1856 this->flushRenderTarget(glRT, pipeline.getDisableOutputConversionToSRGB()); 1857 1858 return true; 1859 } 1860 1861 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, 1862 const GrBuffer* indexBuffer, 1863 const GrBuffer* vertexBuffer, 1864 int baseVertex, 1865 const GrBuffer* instanceBuffer, 1866 int baseInstance) { 1867 using EnablePrimitiveRestart = GrGLAttribArrayState::EnablePrimitiveRestart; 1868 1869 GrGLAttribArrayState* attribState; 1870 if (indexBuffer) { 1871 SkASSERT(indexBuffer && !indexBuffer->isMapped()); 1872 attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer); 1873 } else { 1874 attribState = fHWVertexArrayState.bindInternalVertexArray(this); 1875 } 1876 1877 struct { 1878 const GrBuffer* fBuffer; 1879 int fStride; 1880 size_t fBufferOffset; 1881 } bindings[2]; 1882 1883 if (int vertexStride = primProc.getVertexStride()) { 1884 SkASSERT(vertexBuffer && !vertexBuffer->isMapped()); 1885 bindings[0].fBuffer = vertexBuffer; 1886 bindings[0].fStride = vertexStride; 1887 bindings[0].fBufferOffset = vertexBuffer->baseOffset() + baseVertex * vertexStride; 1888 } 1889 if (int instanceStride = primProc.getInstanceStride()) { 1890 SkASSERT(instanceBuffer && !instanceBuffer->isMapped()); 1891 bindings[1].fBuffer = instanceBuffer; 1892 bindings[1].fStride = instanceStride; 1893 bindings[1].fBufferOffset = instanceBuffer->baseOffset() + baseInstance * instanceStride; 1894 } 1895 1896 int numAttribs = primProc.numAttribs(); 1897 auto enableRestart = EnablePrimitiveRestart(primProc.willUsePrimitiveRestart() && indexBuffer); 1898 attribState->enableVertexArrays(this, numAttribs, enableRestart); 1899 1900 for (int i = 0; i < numAttribs; ++i) { 1901 using InputRate = GrPrimitiveProcessor::Attribute::InputRate; 1902 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(i); 1903 const int divisor = InputRate::kPerInstance == attrib.fInputRate ? 1 : 0; 1904 const auto& binding = bindings[divisor]; 1905 attribState->set(this, i, binding.fBuffer, attrib.fType, binding.fStride, 1906 binding.fBufferOffset + attrib.fOffsetInRecord, divisor); 1907 } 1908 } 1909 1910 GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrBuffer* buffer) { 1911 this->handleDirtyContext(); 1912 1913 // Index buffer state is tied to the vertex array. 1914 if (kIndex_GrBufferType == type) { 1915 this->bindVertexArray(0); 1916 } 1917 1918 SkASSERT(type >= 0 && type <= kLast_GrBufferType); 1919 auto& bufferState = fHWBufferState[type]; 1920 1921 if (buffer->uniqueID() != bufferState.fBoundBufferUniqueID) { 1922 if (buffer->isCPUBacked()) { 1923 if (!bufferState.fBufferZeroKnownBound) { 1924 GL_CALL(BindBuffer(bufferState.fGLTarget, 0)); 1925 } 1926 } else { 1927 const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(buffer); 1928 GL_CALL(BindBuffer(bufferState.fGLTarget, glBuffer->bufferID())); 1929 } 1930 bufferState.fBufferZeroKnownBound = buffer->isCPUBacked(); 1931 bufferState.fBoundBufferUniqueID = buffer->uniqueID(); 1932 } 1933 1934 return bufferState.fGLTarget; 1935 } 1936 1937 void GrGLGpu::notifyBufferReleased(const GrGLBuffer* buffer) { 1938 if (buffer->hasAttachedToTexture()) { 1939 // Detach this buffer from any textures to ensure the underlying memory is freed. 1940 GrGpuResource::UniqueID uniqueID = buffer->uniqueID(); 1941 for (int i = fHWMaxUsedBufferTextureUnit; i >= 0; --i) { 1942 auto& buffTex = fHWBufferTextures[i]; 1943 if (uniqueID != buffTex.fAttachedBufferUniqueID) { 1944 continue; 1945 } 1946 if (i == fHWMaxUsedBufferTextureUnit) { 1947 --fHWMaxUsedBufferTextureUnit; 1948 } 1949 1950 this->setTextureUnit(i); 1951 if (!buffTex.fKnownBound) { 1952 SkASSERT(buffTex.fTextureID); 1953 GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID)); 1954 buffTex.fKnownBound = true; 1955 } 1956 GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER, 1957 this->glCaps().configSizedInternalFormat(buffTex.fTexelConfig), 0)); 1958 } 1959 } 1960 } 1961 1962 void GrGLGpu::disableScissor() { 1963 if (kNo_TriState != fHWScissorSettings.fEnabled) { 1964 GL_CALL(Disable(GR_GL_SCISSOR_TEST)); 1965 fHWScissorSettings.fEnabled = kNo_TriState; 1966 return; 1967 } 1968 } 1969 1970 void GrGLGpu::clear(const GrFixedClip& clip, GrColor color, 1971 GrRenderTarget* target, GrSurfaceOrigin origin) { 1972 // parent class should never let us get here with no RT 1973 SkASSERT(target); 1974 1975 this->handleDirtyContext(); 1976 1977 GrGLfloat r, g, b, a; 1978 static const GrGLfloat scale255 = 1.f / 255.f; 1979 a = GrColorUnpackA(color) * scale255; 1980 GrGLfloat scaleRGB = scale255; 1981 r = GrColorUnpackR(color) * scaleRGB; 1982 g = GrColorUnpackG(color) * scaleRGB; 1983 b = GrColorUnpackB(color) * scaleRGB; 1984 1985 if (this->glCaps().useDrawToClearColor()) { 1986 this->clearColorAsDraw(clip, r, g, b, a, target, origin); 1987 return; 1988 } 1989 1990 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); 1991 1992 if (clip.scissorEnabled()) { 1993 this->flushRenderTarget(glRT, origin, clip.scissorRect()); 1994 } else { 1995 this->flushRenderTarget(glRT); 1996 } 1997 this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); 1998 this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); 1999 2000 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 2001 fHWWriteToColor = kYes_TriState; 2002 2003 if (this->glCaps().clearToBoundaryValuesIsBroken() && 2004 (1 == r || 0 == r) && (1 == g || 0 == g) && (1 == b || 0 == b) && (1 == a || 0 == a)) { 2005 static const GrGLfloat safeAlpha1 = nextafter(1.f, 2.f); 2006 static const GrGLfloat safeAlpha0 = nextafter(0.f, -1.f); 2007 a = (1 == a) ? safeAlpha1 : safeAlpha0; 2008 } 2009 GL_CALL(ClearColor(r, g, b, a)); 2010 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); 2011 } 2012 2013 void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) { 2014 if (!target) { 2015 return; 2016 } 2017 2018 GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment(); 2019 // this should only be called internally when we know we have a 2020 // stencil buffer. 2021 SkASSERT(sb); 2022 2023 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); 2024 this->flushRenderTargetNoColorWrites(glRT); 2025 2026 this->disableScissor(); 2027 this->disableWindowRectangles(); 2028 2029 GL_CALL(StencilMask(0xffffffff)); 2030 GL_CALL(ClearStencil(clearValue)); 2031 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 2032 fHWStencilSettings.invalidate(); 2033 if (!clearValue) { 2034 sb->cleared(); 2035 } 2036 } 2037 2038 void GrGLGpu::clearStencilClip(const GrFixedClip& clip, 2039 bool insideStencilMask, 2040 GrRenderTarget* target, GrSurfaceOrigin origin) { 2041 SkASSERT(target); 2042 this->handleDirtyContext(); 2043 2044 if (this->glCaps().useDrawToClearStencilClip()) { 2045 this->clearStencilClipAsDraw(clip, insideStencilMask, target, origin); 2046 return; 2047 } 2048 2049 GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment(); 2050 // this should only be called internally when we know we have a 2051 // stencil buffer. 2052 SkASSERT(sb); 2053 GrGLint stencilBitCount = sb->bits(); 2054 #if 0 2055 SkASSERT(stencilBitCount > 0); 2056 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); 2057 #else 2058 // we could just clear the clip bit but when we go through 2059 // ANGLE a partial stencil mask will cause clears to be 2060 // turned into draws. Our contract on GrOpList says that 2061 // changing the clip between stencil passes may or may not 2062 // zero the client's clip bits. So we just clear the whole thing. 2063 static const GrGLint clipStencilMask = ~0; 2064 #endif 2065 GrGLint value; 2066 if (insideStencilMask) { 2067 value = (1 << (stencilBitCount - 1)); 2068 } else { 2069 value = 0; 2070 } 2071 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); 2072 this->flushRenderTargetNoColorWrites(glRT); 2073 2074 this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); 2075 this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); 2076 2077 GL_CALL(StencilMask((uint32_t) clipStencilMask)); 2078 GL_CALL(ClearStencil(value)); 2079 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 2080 fHWStencilSettings.invalidate(); 2081 } 2082 2083 static bool read_pixels_pays_for_y_flip(GrSurfaceOrigin origin, const GrGLCaps& caps, 2084 int width, int height, GrPixelConfig config, 2085 size_t rowBytes) { 2086 // If the surface is already TopLeft, we don't need to flip. 2087 if (kTopLeft_GrSurfaceOrigin == origin) { 2088 return false; 2089 } 2090 2091 // If the read is really small or smaller than the min texture size, don't force a draw. 2092 static const int kMinSize = 32; 2093 if (width < kMinSize || height < kMinSize) { 2094 return false; 2095 } 2096 2097 // if GL can do the flip then we'll never pay for it. 2098 if (caps.packFlipYSupport()) { 2099 return false; 2100 } 2101 2102 // If we have to do memcpy to handle non-trim rowBytes then we 2103 // get the flip for free. Otherwise it costs. 2104 // Note that we're assuming that 0 rowBytes has already been handled and that the width has been 2105 // clipped. 2106 return caps.packRowLengthSupport() || GrBytesPerPixel(config) * width == rowBytes; 2107 } 2108 2109 bool GrGLGpu::readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig) { 2110 #ifdef SK_BUILD_FOR_MAC 2111 // Chromium may ask us to read back from locked IOSurfaces. Calling the command buffer's 2112 // glGetIntegerv() with GL_IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE causes the command buffer 2113 // to make a call to check the framebuffer status which can hang the driver. So in Mac Chromium 2114 // we always use a temporary surface to test for read pixels support. 2115 // https://www.crbug.com/662802 2116 if (this->glContext().driver() == kChromium_GrGLDriver) { 2117 return this->readPixelsSupported(target->config(), readConfig); 2118 } 2119 #endif 2120 auto bindRenderTarget = [this, target]() -> bool { 2121 this->flushRenderTargetNoColorWrites(static_cast<GrGLRenderTarget*>(target)); 2122 return true; 2123 }; 2124 auto unbindRenderTarget = []{}; 2125 auto getIntegerv = [this](GrGLenum query, GrGLint* value) { 2126 GR_GL_GetIntegerv(this->glInterface(), query, value); 2127 }; 2128 GrPixelConfig rtConfig = target->config(); 2129 return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget, 2130 unbindRenderTarget); 2131 } 2132 2133 bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConfig) { 2134 sk_sp<GrTexture> temp; 2135 auto bindRenderTarget = [this, rtConfig, &temp]() -> bool { 2136 GrSurfaceDesc desc; 2137 desc.fConfig = rtConfig; 2138 desc.fWidth = desc.fHeight = 16; 2139 if (this->glCaps().isConfigRenderable(rtConfig)) { 2140 desc.fFlags = kRenderTarget_GrSurfaceFlag; 2141 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; 2142 temp = this->createTexture(desc, SkBudgeted::kNo); 2143 if (!temp) { 2144 return false; 2145 } 2146 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(temp->asRenderTarget()); 2147 this->flushRenderTargetNoColorWrites(glrt); 2148 return true; 2149 } else if (this->glCaps().canConfigBeFBOColorAttachment(rtConfig)) { 2150 desc.fOrigin = kTopLeft_GrSurfaceOrigin; 2151 temp = this->createTexture(desc, SkBudgeted::kNo); 2152 if (!temp) { 2153 return false; 2154 } 2155 GrGLIRect vp; 2156 this->bindSurfaceFBOForPixelOps(temp.get(), GR_GL_FRAMEBUFFER, &vp, kDst_TempFBOTarget); 2157 fHWBoundRenderTargetUniqueID.makeInvalid(); 2158 return true; 2159 } 2160 return false; 2161 }; 2162 auto unbindRenderTarget = [this, &temp]() { 2163 this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, temp.get()); 2164 }; 2165 auto getIntegerv = [this](GrGLenum query, GrGLint* value) { 2166 GR_GL_GetIntegerv(this->glInterface(), query, value); 2167 }; 2168 return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget, 2169 unbindRenderTarget); 2170 } 2171 2172 bool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig) { 2173 if (GrRenderTarget* rt = surfaceForConfig->asRenderTarget()) { 2174 return this->readPixelsSupported(rt, readConfig); 2175 } else { 2176 GrPixelConfig config = surfaceForConfig->config(); 2177 return this->readPixelsSupported(config, readConfig); 2178 } 2179 } 2180 2181 bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width, 2182 int height, size_t rowBytes, GrColorType dstColorType, 2183 DrawPreference* drawPreference, 2184 ReadPixelTempDrawInfo* tempDrawInfo) { 2185 // We don't want to introduce a sRGB conversion if we trigger a draw. 2186 auto dstConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(srcSurface->config()); 2187 if (*drawPreference != kNoDraw_DrawPreference) { 2188 // We assume the base class has only inserted a draw for sRGB reasons. So the 2189 // the temp surface has the config of the dst data. There is no swizzling, nor dst config 2190 // spoofing. 2191 SkASSERT(tempDrawInfo->fReadColorType == dstColorType); 2192 SkASSERT(GrPixelConfigToColorType(tempDrawInfo->fTempSurfaceDesc.fConfig) == dstColorType); 2193 SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA()); 2194 // Don't undo a sRGB conversion introduced by our caller via an intermediate draw. 2195 dstConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(tempDrawInfo->fTempSurfaceDesc.fConfig); 2196 } 2197 if (GrColorTypeIsAlphaOnly(dstColorType)) { 2198 dstConfigSRGBEncoded = GrSRGBEncoded::kNo; 2199 } 2200 GrPixelConfig srcConfig = srcSurface->config(); 2201 2202 tempDrawInfo->fTempSurfaceFit = this->glCaps().partialFBOReadIsSlow() ? SkBackingFit::kExact 2203 : SkBackingFit::kApprox; 2204 2205 // TODO: Update this logic to use color type. 2206 auto dstAsConfig = GrColorTypeToPixelConfig(dstColorType, dstConfigSRGBEncoded); 2207 2208 if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == dstAsConfig && 2209 this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelConfig)) { 2210 tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig; 2211 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2212 tempDrawInfo->fReadColorType = GrColorType::kBGRA_8888; 2213 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2214 } else if (this->glCaps().rgbaToBgraReadbackConversionsAreSlow() && 2215 GrBytesPerPixel(dstAsConfig) == 4 && 2216 GrPixelConfigSwapRAndB(dstAsConfig) == srcConfig && 2217 this->readPixelsSupported(srcSurface, srcConfig)) { 2218 // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa. 2219 // Better to do a draw with a R/B swap and then read as the original config. 2220 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 2221 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2222 tempDrawInfo->fReadColorType = GrPixelConfigToColorType(srcConfig); 2223 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2224 } else if (!this->readPixelsSupported(srcSurface, dstAsConfig)) { 2225 if (kBGRA_8888_GrPixelConfig == dstAsConfig && 2226 this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig) && 2227 this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPixelConfig)) { 2228 // We're trying to read BGRA but it's not supported. If RGBA is renderable and 2229 // we can read it back, then do a swizzling draw to a RGBA and read it back (which 2230 // will effectively be BGRA). 2231 tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; 2232 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2233 tempDrawInfo->fReadColorType = GrColorType::kRGBA_8888; 2234 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2235 } else if (kSBGRA_8888_GrPixelConfig == dstAsConfig && 2236 this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) && 2237 this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, 2238 kSRGBA_8888_GrPixelConfig)) { 2239 // We're trying to read sBGRA but it's not supported. If sRGBA is renderable and 2240 // we can read it back, then do a swizzling draw to a sRGBA and read it back (which 2241 // will effectively be sBGRA). 2242 tempDrawInfo->fTempSurfaceDesc.fConfig = kSRGBA_8888_GrPixelConfig; 2243 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2244 tempDrawInfo->fReadColorType = GrColorType::kRGBA_8888; 2245 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2246 } else if (kAlpha_8_GrPixelConfig == dstAsConfig) { 2247 // onReadPixels implements a fallback for cases where we want to read kAlpha_8, 2248 // it's unsupported, but 32bit RGBA reads are supported. 2249 if (!this->readPixelsSupported(srcSurface, kRGBA_8888_GrPixelConfig)) { 2250 // If we can't read RGBA from the src try to draw to a kRGBA_8888 (or kSRGBA_8888) 2251 // first and then onReadPixels will read that to a 32bit temporary buffer. 2252 if (this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig)) { 2253 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2254 tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; 2255 tempDrawInfo->fReadColorType = GrColorType::kAlpha_8; 2256 } else { 2257 return false; 2258 } 2259 } else { 2260 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 2261 SkASSERT(tempDrawInfo->fReadColorType == GrColorType::kAlpha_8); 2262 } 2263 } else if (kRGBA_half_GrPixelConfig == dstAsConfig && 2264 this->readPixelsSupported(srcSurface, kRGBA_float_GrPixelConfig)) { 2265 // If reading in half float format is not supported, then read in float format. 2266 return true; 2267 } else if (this->glCaps().canConfigBeFBOColorAttachment(dstAsConfig) && 2268 this->readPixelsSupported(dstAsConfig, dstAsConfig)) { 2269 // Do a draw to convert from the src config to the read config. 2270 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2271 tempDrawInfo->fTempSurfaceDesc.fConfig = dstAsConfig; 2272 tempDrawInfo->fReadColorType = dstColorType; 2273 } else { 2274 return false; 2275 } 2276 } 2277 2278 if ((srcSurface->asRenderTarget() || this->glCaps().canConfigBeFBOColorAttachment(srcConfig)) && 2279 read_pixels_pays_for_y_flip(srcOrigin, this->glCaps(), width, height, dstAsConfig, 2280 rowBytes)) { 2281 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2282 } 2283 2284 return true; 2285 } 2286 2287 bool GrGLGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top, int width, 2288 int height, GrColorType dstColorType, void* buffer, size_t rowBytes) { 2289 SkASSERT(surface); 2290 2291 GrGLRenderTarget* renderTarget = static_cast<GrGLRenderTarget*>(surface->asRenderTarget()); 2292 if (!renderTarget && !this->glCaps().canConfigBeFBOColorAttachment(surface->config())) { 2293 return false; 2294 } 2295 2296 // TODO: Avoid this conversion by making GrGLCaps work with color types. 2297 auto dstAsConfig = GrColorTypeToPixelConfig(dstColorType, GrSRGBEncoded::kNo); 2298 2299 // We have a special case fallback for reading eight bit alpha. We will read back all four 8 2300 // bit channels as RGBA and then extract A. 2301 if (!this->readPixelsSupported(surface, dstAsConfig)) { 2302 if (kAlpha_8_GrPixelConfig == dstAsConfig && 2303 this->readPixelsSupported(surface, kRGBA_8888_GrPixelConfig)) { 2304 std::unique_ptr<uint32_t[]> temp(new uint32_t[width * height * 4]); 2305 if (this->onReadPixels(surface, origin, left, top, width, height, 2306 GrColorType::kRGBA_8888, temp.get(), width * 4)) { 2307 uint8_t* dst = reinterpret_cast<uint8_t*>(buffer); 2308 for (int j = 0; j < height; ++j) { 2309 for (int i = 0; i < width; ++i) { 2310 dst[j*rowBytes + i] = (0xFF000000U & temp[j*width+i]) >> 24; 2311 } 2312 } 2313 return true; 2314 } 2315 } 2316 2317 // If reading in half float format is not supported, then read in a temporary float buffer 2318 // and convert to half float. 2319 if (kRGBA_half_GrPixelConfig == dstAsConfig && 2320 this->readPixelsSupported(surface, kRGBA_float_GrPixelConfig)) { 2321 std::unique_ptr<float[]> temp(new float[width * height * 4]); 2322 if (this->onReadPixels(surface, origin, left, top, width, height, 2323 GrColorType::kRGBA_F32, temp.get(), width * sizeof(float) * 4)) { 2324 uint8_t* dst = reinterpret_cast<uint8_t*>(buffer); 2325 float* src = temp.get(); 2326 for (int j = 0; j < height; ++j) { 2327 SkHalf* dstRow = reinterpret_cast<SkHalf*>(dst); 2328 for (int i = 0; i < width; ++i) { 2329 for (int color = 0; color < 4; color++) { 2330 *dstRow++ = SkFloatToHalf(*src++); 2331 } 2332 } 2333 dst += rowBytes; 2334 } 2335 return true; 2336 } 2337 } 2338 return false; 2339 } 2340 2341 GrGLenum externalFormat; 2342 GrGLenum externalType; 2343 if (!this->glCaps().getReadPixelsFormat(surface->config(), dstAsConfig, &externalFormat, 2344 &externalType)) { 2345 return false; 2346 } 2347 bool flipY = kBottomLeft_GrSurfaceOrigin == origin; 2348 2349 GrGLIRect glvp; 2350 if (renderTarget) { 2351 // resolve the render target if necessary 2352 switch (renderTarget->getResolveType()) { 2353 case GrGLRenderTarget::kCantResolve_ResolveType: 2354 return false; 2355 case GrGLRenderTarget::kAutoResolves_ResolveType: 2356 this->flushRenderTargetNoColorWrites(renderTarget); 2357 break; 2358 case GrGLRenderTarget::kCanResolve_ResolveType: 2359 this->onResolveRenderTarget(renderTarget); 2360 // we don't track the state of the READ FBO ID. 2361 fStats.incRenderTargetBinds(); 2362 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID())); 2363 break; 2364 default: 2365 SK_ABORT("Unknown resolve type"); 2366 } 2367 glvp = renderTarget->getViewport(); 2368 } else { 2369 // Use a temporary FBO. 2370 this->bindSurfaceFBOForPixelOps(surface, GR_GL_FRAMEBUFFER, &glvp, kSrc_TempFBOTarget); 2371 fHWBoundRenderTargetUniqueID.makeInvalid(); 2372 } 2373 2374 // the read rect is viewport-relative 2375 GrGLIRect readRect; 2376 readRect.setRelativeTo(glvp, left, top, width, height, origin); 2377 2378 int bytesPerPixel = GrBytesPerPixel(dstAsConfig); 2379 size_t tightRowBytes = bytesPerPixel * width; 2380 2381 size_t readDstRowBytes = tightRowBytes; 2382 void* readDst = buffer; 2383 2384 // determine if GL can read using the passed rowBytes or if we need 2385 // a scratch buffer. 2386 SkAutoSMalloc<32 * sizeof(GrColor)> scratch; 2387 if (rowBytes != tightRowBytes) { 2388 if (this->glCaps().packRowLengthSupport() && !(rowBytes % bytesPerPixel)) { 2389 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 2390 static_cast<GrGLint>(rowBytes / bytesPerPixel))); 2391 readDstRowBytes = rowBytes; 2392 } else { 2393 scratch.reset(tightRowBytes * height); 2394 readDst = scratch.get(); 2395 } 2396 } 2397 if (flipY && this->glCaps().packFlipYSupport()) { 2398 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1)); 2399 } 2400 GL_CALL(PixelStorei(GR_GL_PACK_ALIGNMENT, config_alignment(dstAsConfig))); 2401 2402 GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom, 2403 readRect.fWidth, readRect.fHeight, 2404 externalFormat, externalType, readDst)); 2405 if (readDstRowBytes != tightRowBytes) { 2406 SkASSERT(this->glCaps().packRowLengthSupport()); 2407 GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 2408 } 2409 if (flipY && this->glCaps().packFlipYSupport()) { 2410 GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0)); 2411 flipY = false; 2412 } 2413 2414 // now reverse the order of the rows, since GL's are bottom-to-top, but our 2415 // API presents top-to-bottom. We must preserve the padding contents. Note 2416 // that the above readPixels did not overwrite the padding. 2417 if (readDst == buffer) { 2418 SkASSERT(rowBytes == readDstRowBytes); 2419 if (flipY) { 2420 scratch.reset(tightRowBytes); 2421 void* tmpRow = scratch.get(); 2422 // flip y in-place by rows 2423 const int halfY = height >> 1; 2424 char* top = reinterpret_cast<char*>(buffer); 2425 char* bottom = top + (height - 1) * rowBytes; 2426 for (int y = 0; y < halfY; y++) { 2427 memcpy(tmpRow, top, tightRowBytes); 2428 memcpy(top, bottom, tightRowBytes); 2429 memcpy(bottom, tmpRow, tightRowBytes); 2430 top += rowBytes; 2431 bottom -= rowBytes; 2432 } 2433 } 2434 } else { 2435 SkASSERT(readDst != buffer); 2436 SkASSERT(rowBytes != tightRowBytes); 2437 // copy from readDst to buffer while flipping y 2438 // const int halfY = height >> 1; 2439 const char* src = reinterpret_cast<const char*>(readDst); 2440 char* dst = reinterpret_cast<char*>(buffer); 2441 if (flipY) { 2442 dst += (height-1) * rowBytes; 2443 } 2444 for (int y = 0; y < height; y++) { 2445 memcpy(dst, src, tightRowBytes); 2446 src += readDstRowBytes; 2447 if (!flipY) { 2448 dst += rowBytes; 2449 } else { 2450 dst -= rowBytes; 2451 } 2452 } 2453 } 2454 if (!renderTarget) { 2455 this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, surface); 2456 } 2457 return true; 2458 } 2459 2460 GrGpuRTCommandBuffer* GrGLGpu::createCommandBuffer( 2461 GrRenderTarget* rt, GrSurfaceOrigin origin, 2462 const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo, 2463 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) { 2464 return new GrGLGpuRTCommandBuffer(this, rt, origin, colorInfo, stencilInfo); 2465 } 2466 2467 GrGpuTextureCommandBuffer* GrGLGpu::createCommandBuffer(GrTexture* texture, 2468 GrSurfaceOrigin origin) { 2469 return new GrGLGpuTextureCommandBuffer(this, texture, origin); 2470 } 2471 2472 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, GrSurfaceOrigin origin, 2473 const SkIRect& bounds, bool disableSRGB) { 2474 this->flushRenderTargetNoColorWrites(target, disableSRGB); 2475 this->didWriteToSurface(target, origin, &bounds); 2476 } 2477 2478 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, bool disableSRGB) { 2479 this->flushRenderTargetNoColorWrites(target, disableSRGB); 2480 this->didWriteToSurface(target, kTopLeft_GrSurfaceOrigin, nullptr); 2481 } 2482 2483 void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target, bool disableSRGB) { 2484 SkASSERT(target); 2485 GrGpuResource::UniqueID rtID = target->uniqueID(); 2486 if (fHWBoundRenderTargetUniqueID != rtID) { 2487 fStats.incRenderTargetBinds(); 2488 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); 2489 #ifdef SK_DEBUG 2490 // don't do this check in Chromium -- this is causing 2491 // lots of repeated command buffer flushes when the compositor is 2492 // rendering with Ganesh, which is really slow; even too slow for 2493 // Debug mode. 2494 if (kChromium_GrGLDriver != this->glContext().driver()) { 2495 GrGLenum status; 2496 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 2497 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 2498 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x\n", status); 2499 } 2500 } 2501 #endif 2502 fHWBoundRenderTargetUniqueID = rtID; 2503 this->flushViewport(target->getViewport()); 2504 } 2505 2506 if (this->glCaps().srgbWriteControl()) { 2507 this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !disableSRGB); 2508 } 2509 } 2510 2511 void GrGLGpu::flushFramebufferSRGB(bool enable) { 2512 if (enable && kYes_TriState != fHWSRGBFramebuffer) { 2513 GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB)); 2514 fHWSRGBFramebuffer = kYes_TriState; 2515 } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) { 2516 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); 2517 fHWSRGBFramebuffer = kNo_TriState; 2518 } 2519 } 2520 2521 void GrGLGpu::flushViewport(const GrGLIRect& viewport) { 2522 if (fHWViewport != viewport) { 2523 viewport.pushToGLViewport(this->glInterface()); 2524 fHWViewport = viewport; 2525 } 2526 } 2527 2528 #define SWAP_PER_DRAW 0 2529 2530 #if SWAP_PER_DRAW 2531 #if defined(SK_BUILD_FOR_MAC) 2532 #include <AGL/agl.h> 2533 #elif defined(SK_BUILD_FOR_WIN) 2534 #include <gl/GL.h> 2535 void SwapBuf() { 2536 DWORD procID = GetCurrentProcessId(); 2537 HWND hwnd = GetTopWindow(GetDesktopWindow()); 2538 while(hwnd) { 2539 DWORD wndProcID = 0; 2540 GetWindowThreadProcessId(hwnd, &wndProcID); 2541 if(wndProcID == procID) { 2542 SwapBuffers(GetDC(hwnd)); 2543 } 2544 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); 2545 } 2546 } 2547 #endif 2548 #endif 2549 2550 void GrGLGpu::draw(const GrPipeline& pipeline, 2551 const GrPrimitiveProcessor& primProc, 2552 const GrMesh meshes[], 2553 const GrPipeline::DynamicState dynamicStates[], 2554 int meshCount) { 2555 this->handleDirtyContext(); 2556 2557 bool hasPoints = false; 2558 for (int i = 0; i < meshCount; ++i) { 2559 if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) { 2560 hasPoints = true; 2561 break; 2562 } 2563 } 2564 if (!this->flushGLState(pipeline, primProc, hasPoints)) { 2565 return; 2566 } 2567 2568 for (int i = 0; i < meshCount; ++i) { 2569 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) { 2570 this->xferBarrier(pipeline.renderTarget(), barrierType); 2571 } 2572 2573 if (dynamicStates) { 2574 if (pipeline.getScissorState().enabled()) { 2575 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget()); 2576 this->flushScissor(dynamicStates[i].fScissorRect, 2577 glRT->getViewport(), pipeline.proxy()->origin()); 2578 } 2579 } 2580 if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() && 2581 GrIsPrimTypeLines(meshes[i].primitiveType()) && 2582 !GrIsPrimTypeLines(fLastPrimitiveType)) { 2583 GL_CALL(Enable(GR_GL_CULL_FACE)); 2584 GL_CALL(Disable(GR_GL_CULL_FACE)); 2585 } 2586 meshes[i].sendToGpu(primProc, this); 2587 fLastPrimitiveType = meshes[i].primitiveType(); 2588 } 2589 2590 #if SWAP_PER_DRAW 2591 glFlush(); 2592 #if defined(SK_BUILD_FOR_MAC) 2593 aglSwapBuffers(aglGetCurrentContext()); 2594 int set_a_break_pt_here = 9; 2595 aglSwapBuffers(aglGetCurrentContext()); 2596 #elif defined(SK_BUILD_FOR_WIN) 2597 SwapBuf(); 2598 int set_a_break_pt_here = 9; 2599 SwapBuf(); 2600 #endif 2601 #endif 2602 } 2603 2604 static GrGLenum gr_primitive_type_to_gl_mode(GrPrimitiveType primitiveType) { 2605 switch (primitiveType) { 2606 case GrPrimitiveType::kTriangles: 2607 return GR_GL_TRIANGLES; 2608 case GrPrimitiveType::kTriangleStrip: 2609 return GR_GL_TRIANGLE_STRIP; 2610 case GrPrimitiveType::kTriangleFan: 2611 return GR_GL_TRIANGLE_FAN; 2612 case GrPrimitiveType::kPoints: 2613 return GR_GL_POINTS; 2614 case GrPrimitiveType::kLines: 2615 return GR_GL_LINES; 2616 case GrPrimitiveType::kLineStrip: 2617 return GR_GL_LINE_STRIP; 2618 case GrPrimitiveType::kLinesAdjacency: 2619 return GR_GL_LINES_ADJACENCY; 2620 } 2621 SK_ABORT("invalid GrPrimitiveType"); 2622 return GR_GL_TRIANGLES; 2623 } 2624 2625 void GrGLGpu::sendMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType primitiveType, 2626 const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) { 2627 const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); 2628 if (this->glCaps().drawArraysBaseVertexIsBroken()) { 2629 this->setupGeometry(primProc, nullptr, vertexBuffer, baseVertex, nullptr, 0); 2630 GL_CALL(DrawArrays(glPrimType, 0, vertexCount)); 2631 } else { 2632 this->setupGeometry(primProc, nullptr, vertexBuffer, 0, nullptr, 0); 2633 GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount)); 2634 } 2635 fStats.incNumDraws(); 2636 } 2637 2638 void GrGLGpu::sendIndexedMeshToGpu(const GrPrimitiveProcessor& primProc, 2639 GrPrimitiveType primitiveType, const GrBuffer* indexBuffer, 2640 int indexCount, int baseIndex, uint16_t minIndexValue, 2641 uint16_t maxIndexValue, const GrBuffer* vertexBuffer, 2642 int baseVertex) { 2643 const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); 2644 GrGLvoid* const indices = reinterpret_cast<void*>(indexBuffer->baseOffset() + 2645 sizeof(uint16_t) * baseIndex); 2646 2647 this->setupGeometry(primProc, indexBuffer, vertexBuffer, baseVertex, nullptr, 0); 2648 2649 if (this->glCaps().drawRangeElementsSupport()) { 2650 GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount, 2651 GR_GL_UNSIGNED_SHORT, indices)); 2652 } else { 2653 GL_CALL(DrawElements(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, indices)); 2654 } 2655 fStats.incNumDraws(); 2656 } 2657 2658 void GrGLGpu::sendInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType 2659 primitiveType, const GrBuffer* vertexBuffer, 2660 int vertexCount, int baseVertex, 2661 const GrBuffer* instanceBuffer, int instanceCount, 2662 int baseInstance) { 2663 GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); 2664 int maxInstances = this->glCaps().maxInstancesPerDrawArraysWithoutCrashing(instanceCount); 2665 for (int i = 0; i < instanceCount; i += maxInstances) { 2666 this->setupGeometry(primProc, nullptr, vertexBuffer, 0, instanceBuffer, baseInstance + i); 2667 GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, 2668 SkTMin(instanceCount - i, maxInstances))); 2669 fStats.incNumDraws(); 2670 } 2671 } 2672 2673 void GrGLGpu::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, 2674 GrPrimitiveType primitiveType, 2675 const GrBuffer* indexBuffer, int indexCount, 2676 int baseIndex, const GrBuffer* vertexBuffer, 2677 int baseVertex, const GrBuffer* instanceBuffer, 2678 int instanceCount, int baseInstance) { 2679 const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); 2680 GrGLvoid* indices = reinterpret_cast<void*>(indexBuffer->baseOffset() + 2681 sizeof(uint16_t) * baseIndex); 2682 this->setupGeometry(primProc, indexBuffer, vertexBuffer, baseVertex, 2683 instanceBuffer, baseInstance); 2684 GL_CALL(DrawElementsInstanced(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, indices, 2685 instanceCount)); 2686 fStats.incNumDraws(); 2687 } 2688 2689 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { 2690 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); 2691 if (rt->needsResolve()) { 2692 // Some extensions automatically resolves the texture when it is read. 2693 if (this->glCaps().usesMSAARenderBuffers()) { 2694 SkASSERT(rt->textureFBOID() != rt->renderFBOID()); 2695 SkASSERT(rt->textureFBOID() != 0 && rt->renderFBOID() != 0); 2696 fStats.incRenderTargetBinds(); 2697 fStats.incRenderTargetBinds(); 2698 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); 2699 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID())); 2700 // make sure we go through flushRenderTarget() since we've modified 2701 // the bound DRAW FBO ID. 2702 fHWBoundRenderTargetUniqueID.makeInvalid(); 2703 const GrGLIRect& vp = rt->getViewport(); 2704 const SkIRect dirtyRect = rt->getResolveRect(); 2705 // The dirty rect tracked on the RT is always stored in the native coordinates of the 2706 // surface. Choose kTopLeft so no adjustments are made 2707 static constexpr auto kDirtyRectOrigin = kTopLeft_GrSurfaceOrigin; 2708 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { 2709 // Apple's extension uses the scissor as the blit bounds. 2710 GrScissorState scissorState; 2711 scissorState.set(dirtyRect); 2712 this->flushScissor(scissorState, vp, kDirtyRectOrigin); 2713 this->disableWindowRectangles(); 2714 GL_CALL(ResolveMultisampleFramebuffer()); 2715 } else { 2716 int l, b, r, t; 2717 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & 2718 this->glCaps().blitFramebufferSupportFlags()) { 2719 l = 0; 2720 b = 0; 2721 r = target->width(); 2722 t = target->height(); 2723 } else { 2724 GrGLIRect rect; 2725 rect.setRelativeTo(vp, dirtyRect, kDirtyRectOrigin); 2726 l = rect.fLeft; 2727 b = rect.fBottom; 2728 r = rect.fLeft + rect.fWidth; 2729 t = rect.fBottom + rect.fHeight; 2730 } 2731 2732 // BlitFrameBuffer respects the scissor, so disable it. 2733 this->disableScissor(); 2734 this->disableWindowRectangles(); 2735 GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, 2736 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 2737 } 2738 } 2739 rt->flagAsResolved(); 2740 } 2741 } 2742 2743 namespace { 2744 2745 2746 GrGLenum gr_to_gl_stencil_op(GrStencilOp op) { 2747 static const GrGLenum gTable[kGrStencilOpCount] = { 2748 GR_GL_KEEP, // kKeep 2749 GR_GL_ZERO, // kZero 2750 GR_GL_REPLACE, // kReplace 2751 GR_GL_INVERT, // kInvert 2752 GR_GL_INCR_WRAP, // kIncWrap 2753 GR_GL_DECR_WRAP, // kDecWrap 2754 GR_GL_INCR, // kIncClamp 2755 GR_GL_DECR, // kDecClamp 2756 }; 2757 GR_STATIC_ASSERT(0 == (int)GrStencilOp::kKeep); 2758 GR_STATIC_ASSERT(1 == (int)GrStencilOp::kZero); 2759 GR_STATIC_ASSERT(2 == (int)GrStencilOp::kReplace); 2760 GR_STATIC_ASSERT(3 == (int)GrStencilOp::kInvert); 2761 GR_STATIC_ASSERT(4 == (int)GrStencilOp::kIncWrap); 2762 GR_STATIC_ASSERT(5 == (int)GrStencilOp::kDecWrap); 2763 GR_STATIC_ASSERT(6 == (int)GrStencilOp::kIncClamp); 2764 GR_STATIC_ASSERT(7 == (int)GrStencilOp::kDecClamp); 2765 SkASSERT(op < (GrStencilOp)kGrStencilOpCount); 2766 return gTable[(int)op]; 2767 } 2768 2769 void set_gl_stencil(const GrGLInterface* gl, 2770 const GrStencilSettings::Face& face, 2771 GrGLenum glFace) { 2772 GrGLenum glFunc = GrToGLStencilFunc(face.fTest); 2773 GrGLenum glFailOp = gr_to_gl_stencil_op(face.fFailOp); 2774 GrGLenum glPassOp = gr_to_gl_stencil_op(face.fPassOp); 2775 2776 GrGLint ref = face.fRef; 2777 GrGLint mask = face.fTestMask; 2778 GrGLint writeMask = face.fWriteMask; 2779 2780 if (GR_GL_FRONT_AND_BACK == glFace) { 2781 // we call the combined func just in case separate stencil is not 2782 // supported. 2783 GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask)); 2784 GR_GL_CALL(gl, StencilMask(writeMask)); 2785 GR_GL_CALL(gl, StencilOp(glFailOp, GR_GL_KEEP, glPassOp)); 2786 } else { 2787 GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask)); 2788 GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask)); 2789 GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, GR_GL_KEEP, glPassOp)); 2790 } 2791 } 2792 } 2793 2794 void GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings) { 2795 if (stencilSettings.isDisabled()) { 2796 this->disableStencil(); 2797 } else if (fHWStencilSettings != stencilSettings) { 2798 if (kYes_TriState != fHWStencilTestEnabled) { 2799 GL_CALL(Enable(GR_GL_STENCIL_TEST)); 2800 2801 fHWStencilTestEnabled = kYes_TriState; 2802 } 2803 if (stencilSettings.isTwoSided()) { 2804 set_gl_stencil(this->glInterface(), 2805 stencilSettings.front(), 2806 GR_GL_FRONT); 2807 set_gl_stencil(this->glInterface(), 2808 stencilSettings.back(), 2809 GR_GL_BACK); 2810 } else { 2811 set_gl_stencil(this->glInterface(), 2812 stencilSettings.front(), 2813 GR_GL_FRONT_AND_BACK); 2814 } 2815 fHWStencilSettings = stencilSettings; 2816 } 2817 } 2818 2819 void GrGLGpu::disableStencil() { 2820 if (kNo_TriState != fHWStencilTestEnabled) { 2821 GL_CALL(Disable(GR_GL_STENCIL_TEST)); 2822 2823 fHWStencilTestEnabled = kNo_TriState; 2824 fHWStencilSettings.invalidate(); 2825 } 2826 } 2827 2828 void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled) { 2829 // rt is only optional if useHWAA is false. 2830 SkASSERT(rt || !useHWAA); 2831 SkASSERT(!useHWAA || rt->isStencilBufferMultisampled()); 2832 2833 if (this->caps()->multisampleDisableSupport()) { 2834 if (useHWAA) { 2835 if (kYes_TriState != fMSAAEnabled) { 2836 GL_CALL(Enable(GR_GL_MULTISAMPLE)); 2837 fMSAAEnabled = kYes_TriState; 2838 } 2839 } else { 2840 if (kNo_TriState != fMSAAEnabled) { 2841 GL_CALL(Disable(GR_GL_MULTISAMPLE)); 2842 fMSAAEnabled = kNo_TriState; 2843 } 2844 } 2845 } 2846 2847 if (0 != this->caps()->maxRasterSamples()) { 2848 if (useHWAA && GrFSAAType::kMixedSamples == rt->fsaaType() && !stencilEnabled) { 2849 // Since stencil is disabled and we want more samples than are in the color buffer, we 2850 // need to tell the rasterizer explicitly how many to run. 2851 if (kYes_TriState != fHWRasterMultisampleEnabled) { 2852 GL_CALL(Enable(GR_GL_RASTER_MULTISAMPLE)); 2853 fHWRasterMultisampleEnabled = kYes_TriState; 2854 } 2855 int numStencilSamples = rt->numStencilSamples(); 2856 // convert to GL's understanding of sample counts where 0 means nonMSAA. 2857 numStencilSamples = 1 == numStencilSamples ? 0 : numStencilSamples; 2858 if (numStencilSamples != fHWNumRasterSamples) { 2859 SkASSERT(numStencilSamples <= this->caps()->maxRasterSamples()); 2860 GL_CALL(RasterSamples(numStencilSamples, GR_GL_TRUE)); 2861 fHWNumRasterSamples = numStencilSamples; 2862 } 2863 } else { 2864 if (kNo_TriState != fHWRasterMultisampleEnabled) { 2865 GL_CALL(Disable(GR_GL_RASTER_MULTISAMPLE)); 2866 fHWRasterMultisampleEnabled = kNo_TriState; 2867 } 2868 } 2869 } else { 2870 SkASSERT(!useHWAA || GrFSAAType::kMixedSamples != rt->fsaaType() || stencilEnabled); 2871 } 2872 } 2873 2874 void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) { 2875 // Any optimization to disable blending should have already been applied and 2876 // tweaked the equation to "add" or "subtract", and the coeffs to (1, 0). 2877 2878 GrBlendEquation equation = blendInfo.fEquation; 2879 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 2880 GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 2881 bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && 2882 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; 2883 if (blendOff) { 2884 if (kNo_TriState != fHWBlendState.fEnabled) { 2885 GL_CALL(Disable(GR_GL_BLEND)); 2886 2887 // Workaround for the ARM KHR_blend_equation_advanced blacklist issue 2888 // https://code.google.com/p/skia/issues/detail?id=3943 2889 if (kARM_GrGLVendor == this->ctxInfo().vendor() && 2890 GrBlendEquationIsAdvanced(fHWBlendState.fEquation)) { 2891 SkASSERT(this->caps()->advancedBlendEquationSupport()); 2892 // Set to any basic blending equation. 2893 GrBlendEquation blend_equation = kAdd_GrBlendEquation; 2894 GL_CALL(BlendEquation(gXfermodeEquation2Blend[blend_equation])); 2895 fHWBlendState.fEquation = blend_equation; 2896 } 2897 2898 fHWBlendState.fEnabled = kNo_TriState; 2899 } 2900 return; 2901 } 2902 2903 if (kYes_TriState != fHWBlendState.fEnabled) { 2904 GL_CALL(Enable(GR_GL_BLEND)); 2905 2906 fHWBlendState.fEnabled = kYes_TriState; 2907 } 2908 2909 if (fHWBlendState.fEquation != equation) { 2910 GL_CALL(BlendEquation(gXfermodeEquation2Blend[equation])); 2911 fHWBlendState.fEquation = equation; 2912 } 2913 2914 if (GrBlendEquationIsAdvanced(equation)) { 2915 SkASSERT(this->caps()->advancedBlendEquationSupport()); 2916 // Advanced equations have no other blend state. 2917 return; 2918 } 2919 2920 if (fHWBlendState.fSrcCoeff != srcCoeff || fHWBlendState.fDstCoeff != dstCoeff) { 2921 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], 2922 gXfermodeCoeff2Blend[dstCoeff])); 2923 fHWBlendState.fSrcCoeff = srcCoeff; 2924 fHWBlendState.fDstCoeff = dstCoeff; 2925 } 2926 2927 if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff))) { 2928 GrColor blendConst = blendInfo.fBlendConstant; 2929 blendConst = swizzle.applyTo(blendConst); 2930 if (!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst) { 2931 GrGLfloat c[4]; 2932 GrColorToRGBAFloat(blendConst, c); 2933 GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); 2934 fHWBlendState.fConstColor = blendConst; 2935 fHWBlendState.fConstColorValid = true; 2936 } 2937 } 2938 } 2939 2940 static inline GrGLenum wrap_mode_to_gl_wrap(GrSamplerState::WrapMode wrapMode) { 2941 switch (wrapMode) { 2942 case GrSamplerState::WrapMode::kClamp: 2943 return GR_GL_CLAMP_TO_EDGE; 2944 case GrSamplerState::WrapMode::kRepeat: 2945 return GR_GL_REPEAT; 2946 case GrSamplerState::WrapMode::kMirrorRepeat: 2947 return GR_GL_MIRRORED_REPEAT; 2948 }; 2949 SK_ABORT("Unknown wrap mode"); 2950 return 0; 2951 } 2952 2953 static GrGLenum get_component_enum_from_char(char component) { 2954 switch (component) { 2955 case 'r': 2956 return GR_GL_RED; 2957 case 'g': 2958 return GR_GL_GREEN; 2959 case 'b': 2960 return GR_GL_BLUE; 2961 case 'a': 2962 return GR_GL_ALPHA; 2963 default: 2964 SK_ABORT("Unsupported component"); 2965 return 0; 2966 } 2967 } 2968 2969 /** If texture swizzling is available using tex parameters then it is preferred over mangling 2970 the generated shader code. This potentially allows greater reuse of cached shaders. */ 2971 static void get_tex_param_swizzle(GrPixelConfig config, 2972 const GrGLCaps& caps, 2973 GrGLenum* glSwizzle) { 2974 const GrSwizzle& swizzle = caps.configSwizzle(config); 2975 for (int i = 0; i < 4; ++i) { 2976 glSwizzle[i] = get_component_enum_from_char(swizzle.c_str()[i]); 2977 } 2978 } 2979 2980 static GrGLenum filter_to_gl_mag_filter(GrSamplerState::Filter filter) { 2981 switch (filter) { 2982 case GrSamplerState::Filter::kNearest: 2983 return GR_GL_NEAREST; 2984 case GrSamplerState::Filter::kBilerp: 2985 return GR_GL_LINEAR; 2986 case GrSamplerState::Filter::kMipMap: 2987 return GR_GL_LINEAR; 2988 } 2989 SK_ABORT("Unknown filter"); 2990 return 0; 2991 } 2992 2993 static GrGLenum filter_to_gl_min_filter(GrSamplerState::Filter filter) { 2994 switch (filter) { 2995 case GrSamplerState::Filter::kNearest: 2996 return GR_GL_NEAREST; 2997 case GrSamplerState::Filter::kBilerp: 2998 return GR_GL_LINEAR; 2999 case GrSamplerState::Filter::kMipMap: 3000 return GR_GL_LINEAR_MIPMAP_LINEAR; 3001 } 3002 SK_ABORT("Unknown filter"); 3003 return 0; 3004 } 3005 3006 void GrGLGpu::bindTexture(int unitIdx, const GrSamplerState& samplerState, bool allowSRGBInputs, 3007 GrGLTexture* texture, GrSurfaceOrigin textureOrigin) { 3008 SkASSERT(texture); 3009 3010 #ifdef SK_DEBUG 3011 if (!this->caps()->npotTextureTileSupport()) { 3012 if (samplerState.isRepeated()) { 3013 const int w = texture->width(); 3014 const int h = texture->height(); 3015 SkASSERT(SkIsPow2(w) && SkIsPow2(h)); 3016 } 3017 } 3018 #endif 3019 3020 // If we created a rt/tex and rendered to it without using a texture and now we're texturing 3021 // from the rt it will still be the last bound texture, but it needs resolving. So keep this 3022 // out of the "last != next" check. 3023 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget()); 3024 if (texRT) { 3025 this->onResolveRenderTarget(texRT); 3026 } 3027 3028 GrGpuResource::UniqueID textureID = texture->uniqueID(); 3029 GrGLenum target = texture->target(); 3030 if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) { 3031 this->setTextureUnit(unitIdx); 3032 GL_CALL(BindTexture(target, texture->textureID())); 3033 fHWBoundTextureUniqueIDs[unitIdx] = textureID; 3034 } 3035 3036 ResetTimestamp timestamp; 3037 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(×tamp); 3038 bool setAll = timestamp < this->getResetTimestamp(); 3039 GrGLTexture::TexParams newTexParams; 3040 3041 GrSamplerState::Filter filterMode = samplerState.filter(); 3042 3043 if (GrSamplerState::Filter::kMipMap == filterMode) { 3044 if (!this->caps()->mipMapSupport()) { 3045 filterMode = GrSamplerState::Filter::kBilerp; 3046 } 3047 } 3048 3049 newTexParams.fMinFilter = filter_to_gl_min_filter(filterMode); 3050 newTexParams.fMagFilter = filter_to_gl_mag_filter(filterMode); 3051 3052 if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) { 3053 newTexParams.fSRGBDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT; 3054 if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) { 3055 this->setTextureUnit(unitIdx); 3056 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexParams.fSRGBDecode)); 3057 } 3058 } 3059 3060 #ifdef SK_DEBUG 3061 // We were supposed to ensure MipMaps were up-to-date and built correctly before getting here. 3062 if (GrSamplerState::Filter::kMipMap == filterMode) { 3063 SkASSERT(!texture->texturePriv().mipMapsAreDirty()); 3064 if (GrPixelConfigIsSRGB(texture->config())) { 3065 SkDestinationSurfaceColorMode colorMode = allowSRGBInputs 3066 ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware 3067 : SkDestinationSurfaceColorMode::kLegacy; 3068 SkASSERT(texture->texturePriv().mipColorMode() == colorMode); 3069 } 3070 } 3071 #endif 3072 3073 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); 3074 3075 newTexParams.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX()); 3076 newTexParams.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY()); 3077 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizzleRGBA); 3078 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { 3079 this->setTextureUnit(unitIdx); 3080 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMagFilter)); 3081 } 3082 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { 3083 this->setTextureUnit(unitIdx); 3084 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMinFilter)); 3085 } 3086 if (setAll || newTexParams.fMaxMipMapLevel != oldTexParams.fMaxMipMapLevel) { 3087 // These are not supported in ES2 contexts 3088 if (this->glCaps().mipMapLevelAndLodControlSupport()) { 3089 if (newTexParams.fMaxMipMapLevel != 0) { 3090 this->setTextureUnit(unitIdx); 3091 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0)); 3092 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0)); 3093 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LOD, 3094 newTexParams.fMaxMipMapLevel)); 3095 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL, 3096 newTexParams.fMaxMipMapLevel)); 3097 } 3098 } 3099 } 3100 if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { 3101 this->setTextureUnit(unitIdx); 3102 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS)); 3103 } 3104 if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { 3105 this->setTextureUnit(unitIdx); 3106 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT)); 3107 } 3108 if (this->glCaps().textureSwizzleSupport() && 3109 (setAll || memcmp(newTexParams.fSwizzleRGBA, 3110 oldTexParams.fSwizzleRGBA, 3111 sizeof(newTexParams.fSwizzleRGBA)))) { 3112 this->setTextureSwizzle(unitIdx, target, newTexParams.fSwizzleRGBA); 3113 } 3114 texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); 3115 } 3116 3117 void GrGLGpu::bindTexelBuffer(int unitIdx, GrPixelConfig texelConfig, GrGLBuffer* buffer) { 3118 SkASSERT(this->glCaps().canUseConfigWithTexelBuffer(texelConfig)); 3119 SkASSERT(unitIdx >= 0 && unitIdx < fHWBufferTextures.count()); 3120 3121 BufferTexture& buffTex = fHWBufferTextures[unitIdx]; 3122 3123 if (!buffTex.fKnownBound) { 3124 if (!buffTex.fTextureID) { 3125 GL_CALL(GenTextures(1, &buffTex.fTextureID)); 3126 if (!buffTex.fTextureID) { 3127 return; 3128 } 3129 } 3130 3131 this->setTextureUnit(unitIdx); 3132 GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID)); 3133 3134 buffTex.fKnownBound = true; 3135 } 3136 3137 if (buffer->uniqueID() != buffTex.fAttachedBufferUniqueID || 3138 buffTex.fTexelConfig != texelConfig) { 3139 3140 this->setTextureUnit(unitIdx); 3141 GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER, 3142 this->glCaps().configSizedInternalFormat(texelConfig), 3143 buffer->bufferID())); 3144 3145 buffTex.fTexelConfig = texelConfig; 3146 buffTex.fAttachedBufferUniqueID = buffer->uniqueID(); 3147 3148 if (this->glCaps().textureSwizzleSupport() && 3149 this->glCaps().configSwizzle(texelConfig) != buffTex.fSwizzle) { 3150 GrGLenum glSwizzle[4]; 3151 get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); 3152 this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); 3153 buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); 3154 } 3155 3156 buffer->setHasAttachedToTexture(); 3157 fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUnit); 3158 } 3159 } 3160 3161 void GrGLGpu::generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs, 3162 GrGLTexture* texture, GrSurfaceOrigin textureOrigin) { 3163 SkASSERT(texture); 3164 3165 // First, figure out if we need mips for this texture at all: 3166 GrSamplerState::Filter filterMode = params.filter(); 3167 3168 if (GrSamplerState::Filter::kMipMap == filterMode) { 3169 if (!this->caps()->mipMapSupport()) { 3170 filterMode = GrSamplerState::Filter::kBilerp; 3171 } 3172 } 3173 3174 if (GrSamplerState::Filter::kMipMap != filterMode) { 3175 return; 3176 } 3177 3178 // If this is an sRGB texture and the mips were previously built the "other" way 3179 // (gamma-correct vs. not), then we need to rebuild them. We don't need to check for 3180 // srgbSupport - we'll *never* get an sRGB pixel config if we don't support it. 3181 SkDestinationSurfaceColorMode colorMode = allowSRGBInputs 3182 ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware 3183 : SkDestinationSurfaceColorMode::kLegacy; 3184 if (GrPixelConfigIsSRGB(texture->config()) && 3185 colorMode != texture->texturePriv().mipColorMode()) { 3186 texture->texturePriv().markMipMapsDirty(); 3187 } 3188 3189 // If the mips aren't dirty, we're done: 3190 if (!texture->texturePriv().mipMapsAreDirty()) { 3191 return; 3192 } 3193 3194 // If we created a rt/tex and rendered to it without using a texture and now we're texturing 3195 // from the rt it will still be the last bound texture, but it needs resolving. 3196 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget()); 3197 if (texRT) { 3198 this->onResolveRenderTarget(texRT); 3199 } 3200 3201 GrGLenum target = texture->target(); 3202 this->setScratchTextureUnit(); 3203 GL_CALL(BindTexture(target, texture->textureID())); 3204 3205 // Configure sRGB decode, if necessary. This state is the only thing needed for the driver 3206 // call (glGenerateMipmap) to work correctly. Our manual method dirties other state, too. 3207 if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) { 3208 GrGLenum srgbDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT; 3209 // Command buffer's sRGB decode extension doesn't influence mipmap generation correctly. 3210 // If we set this to skip_decode, it appears to suppress sRGB -> Linear for each downsample, 3211 // but not the Linear -> sRGB when writing the next level. The result is that mip-chains 3212 // get progressively brighter as you go down. Forcing this to 'decode' gives predictable 3213 // (and only slightly incorrect) results. See crbug.com/655247 (~comment 28) 3214 if (!this->glCaps().srgbDecodeDisableAffectsMipmaps()) { 3215 srgbDecode = GR_GL_DECODE_EXT; 3216 } 3217 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, srgbDecode)); 3218 } 3219 3220 // Either do manual mipmap generation or (if that fails), just rely on the driver: 3221 if (!this->generateMipmap(texture, textureOrigin, allowSRGBInputs)) { 3222 GL_CALL(GenerateMipmap(target)); 3223 } 3224 3225 texture->texturePriv().markMipMapsClean(); 3226 texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount( 3227 texture->width(), texture->height())); 3228 texture->texturePriv().setMipColorMode(colorMode); 3229 3230 // We have potentially set lots of state on the texture. Easiest to dirty it all: 3231 texture->textureParamsModified(); 3232 } 3233 3234 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]) { 3235 this->setTextureUnit(unitIdx); 3236 if (this->glStandard() == kGLES_GrGLStandard) { 3237 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. 3238 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); 3239 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); 3240 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); 3241 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); 3242 } else { 3243 GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); 3244 GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA, 3245 reinterpret_cast<const GrGLint*>(swizzle))); 3246 } 3247 } 3248 3249 void GrGLGpu::flushColorWrite(bool writeColor) { 3250 if (!writeColor) { 3251 if (kNo_TriState != fHWWriteToColor) { 3252 GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE, 3253 GR_GL_FALSE, GR_GL_FALSE)); 3254 fHWWriteToColor = kNo_TriState; 3255 } 3256 } else { 3257 if (kYes_TriState != fHWWriteToColor) { 3258 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 3259 fHWWriteToColor = kYes_TriState; 3260 } 3261 } 3262 } 3263 3264 void GrGLGpu::setTextureUnit(int unit) { 3265 SkASSERT(unit >= 0 && unit < fHWBoundTextureUniqueIDs.count()); 3266 if (unit != fHWActiveTextureUnitIdx) { 3267 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit)); 3268 fHWActiveTextureUnitIdx = unit; 3269 } 3270 } 3271 3272 void GrGLGpu::setScratchTextureUnit() { 3273 // Bind the last texture unit since it is the least likely to be used by GrGLProgram. 3274 int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1; 3275 if (lastUnitIdx != fHWActiveTextureUnitIdx) { 3276 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx)); 3277 fHWActiveTextureUnitIdx = lastUnitIdx; 3278 } 3279 // clear out the this field so that if a program does use this unit it will rebind the correct 3280 // texture. 3281 fHWBoundTextureUniqueIDs[lastUnitIdx].makeInvalid(); 3282 } 3283 3284 // Determines whether glBlitFramebuffer could be used between src and dst by onCopySurface. 3285 static inline bool can_blit_framebuffer_for_copy_surface( 3286 const GrSurface* dst, GrSurfaceOrigin dstOrigin, 3287 const GrSurface* src, GrSurfaceOrigin srcOrigin, 3288 const SkIRect& srcRect, 3289 const SkIPoint& dstPoint, 3290 const GrGLGpu* gpu) { 3291 auto blitFramebufferFlags = gpu->glCaps().blitFramebufferSupportFlags(); 3292 if (!gpu->glCaps().canConfigBeFBOColorAttachment(dst->config()) || 3293 !gpu->glCaps().canConfigBeFBOColorAttachment(src->config())) { 3294 return false; 3295 } 3296 // Blits are not allowed between int color buffers and float/fixed color buffers. GrGpu should 3297 // have filtered such cases out. 3298 const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture()); 3299 const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture()); 3300 const GrRenderTarget* dstRT = dst->asRenderTarget(); 3301 const GrRenderTarget* srcRT = src->asRenderTarget(); 3302 if (dstTex && dstTex->target() != GR_GL_TEXTURE_2D) { 3303 return false; 3304 } 3305 if (srcTex && srcTex->target() != GR_GL_TEXTURE_2D) { 3306 return false; 3307 } 3308 if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) { 3309 return false; 3310 } 3311 if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) { 3312 // We would mirror to compensate for origin changes. Note that copySurface is 3313 // specified such that the src and dst rects are the same. 3314 if (dstOrigin != srcOrigin) { 3315 return false; 3316 } 3317 } 3318 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) { 3319 if (srcRT && srcRT->numColorSamples() > 1) { 3320 if (dstRT && 1 == dstRT->numColorSamples()) { 3321 return false; 3322 } 3323 if (SkRect::Make(srcRect) != srcRT->getBoundsRect()) { 3324 return false; 3325 } 3326 } 3327 } 3328 if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) { 3329 if (dstRT && dstRT->numColorSamples() > 1) { 3330 return false; 3331 } 3332 } 3333 if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) { 3334 if (dst->config() != src->config()) { 3335 return false; 3336 } 3337 } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) { 3338 const GrRenderTarget* srcRT = src->asRenderTarget(); 3339 if (srcRT && srcRT->numColorSamples() > 1 && dst->config() != src->config()) { 3340 return false; 3341 } 3342 } 3343 if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) { 3344 if (srcRT && srcRT->numColorSamples() > 1) { 3345 if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) { 3346 return false; 3347 } 3348 if (dstOrigin != srcOrigin) { 3349 return false; 3350 } 3351 } 3352 } 3353 return true; 3354 } 3355 3356 static bool rt_has_msaa_render_buffer(const GrGLRenderTarget* rt, const GrGLCaps& glCaps) { 3357 // A RT has a separate MSAA renderbuffer if: 3358 // 1) It's multisampled 3359 // 2) We're using an extension with separate MSAA renderbuffers 3360 // 3) It's not FBO 0, which is special and always auto-resolves 3361 return rt->numColorSamples() > 1 && glCaps.usesMSAARenderBuffers() && rt->renderFBOID() != 0; 3362 } 3363 3364 static inline bool can_copy_texsubimage(const GrSurface* dst, GrSurfaceOrigin dstOrigin, 3365 const GrSurface* src, GrSurfaceOrigin srcOrigin, 3366 const GrGLGpu* gpu) { 3367 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage 3368 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps 3369 // many drivers would allow it to work, but ANGLE does not. 3370 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalFormat() && 3371 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig == src->config())) { 3372 return false; 3373 } 3374 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget()); 3375 // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer) 3376 // then we don't want to copy to the texture but to the MSAA buffer. 3377 if (dstRT && rt_has_msaa_render_buffer(dstRT, gpu->glCaps())) { 3378 return false; 3379 } 3380 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget()); 3381 // If the src is multisampled (and uses an extension where there is a separate MSAA 3382 // renderbuffer) then it is an invalid operation to call CopyTexSubImage 3383 if (srcRT && rt_has_msaa_render_buffer(srcRT, gpu->glCaps())) { 3384 return false; 3385 } 3386 3387 const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture()); 3388 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a 3389 // texture. 3390 if (!dstTex) { 3391 return false; 3392 } 3393 3394 const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture()); 3395 3396 // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring 3397 // is required. 3398 if (gpu->glCaps().canConfigBeFBOColorAttachment(src->config()) && 3399 (!srcTex || srcTex->target() == GR_GL_TEXTURE_2D) && dstTex->target() == GR_GL_TEXTURE_2D && 3400 dstOrigin == srcOrigin) { 3401 return true; 3402 } else { 3403 return false; 3404 } 3405 } 3406 3407 // If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is 3408 // relative to is output. 3409 void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport, 3410 TempFBOTarget tempFBOTarget) { 3411 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget()); 3412 if (!rt) { 3413 SkASSERT(surface->asTexture()); 3414 GrGLTexture* texture = static_cast<GrGLTexture*>(surface->asTexture()); 3415 GrGLuint texID = texture->textureID(); 3416 GrGLenum target = texture->target(); 3417 GrGLuint* tempFBOID; 3418 tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTempDstFBOID; 3419 3420 if (0 == *tempFBOID) { 3421 GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID)); 3422 } 3423 3424 fStats.incRenderTargetBinds(); 3425 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID)); 3426 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, 3427 GR_GL_COLOR_ATTACHMENT0, 3428 target, 3429 texID, 3430 0)); 3431 texture->baseLevelWasBoundToFBO(); 3432 viewport->fLeft = 0; 3433 viewport->fBottom = 0; 3434 viewport->fWidth = surface->width(); 3435 viewport->fHeight = surface->height(); 3436 } else { 3437 fStats.incRenderTargetBinds(); 3438 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID())); 3439 *viewport = rt->getViewport(); 3440 } 3441 } 3442 3443 void GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface) { 3444 // bindSurfaceFBOForPixelOps temporarily binds textures that are not render targets to 3445 if (!surface->asRenderTarget()) { 3446 SkASSERT(surface->asTexture()); 3447 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())->target(); 3448 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, 3449 GR_GL_COLOR_ATTACHMENT0, 3450 textureTarget, 3451 0, 3452 0)); 3453 } 3454 } 3455 3456 bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, 3457 GrSurface* src, GrSurfaceOrigin srcOrigin, 3458 const SkIRect& srcRect, const SkIPoint& dstPoint) { 3459 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the 3460 // swizzle. 3461 if (this->caps()->shaderCaps()->configOutputSwizzle(src->config()) != 3462 this->caps()->shaderCaps()->configOutputSwizzle(dst->config())) { 3463 return false; 3464 } 3465 // Don't prefer copying as a draw if the dst doesn't already have a FBO object. 3466 // This implicitly handles this->glCaps().useDrawInsteadOfAllRenderTargetWrites(). 3467 bool preferCopy = SkToBool(dst->asRenderTarget()); 3468 if (preferCopy && src->asTexture()) { 3469 if (this->copySurfaceAsDraw(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint)) { 3470 return true; 3471 } 3472 } 3473 3474 if (can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this)) { 3475 this->copySurfaceAsCopyTexSubImage(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint); 3476 return true; 3477 } 3478 3479 if (can_blit_framebuffer_for_copy_surface(dst, dstOrigin, src, srcOrigin, 3480 srcRect, dstPoint, this)) { 3481 return this->copySurfaceAsBlitFramebuffer(dst, dstOrigin, src, srcOrigin, 3482 srcRect, dstPoint); 3483 } 3484 3485 if (!preferCopy && src->asTexture()) { 3486 if (this->copySurfaceAsDraw(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint)) { 3487 return true; 3488 } 3489 } 3490 3491 return false; 3492 } 3493 3494 bool GrGLGpu::createCopyProgram(GrTexture* srcTex) { 3495 TRACE_EVENT0("skia", TRACE_FUNC); 3496 3497 int progIdx = TextureToCopyProgramIdx(srcTex); 3498 const GrShaderCaps* shaderCaps = this->caps()->shaderCaps(); 3499 GrSLType samplerType = srcTex->texturePriv().samplerType(); 3500 3501 if (!fCopyProgramArrayBuffer) { 3502 static const GrGLfloat vdata[] = { 3503 0, 0, 3504 0, 1, 3505 1, 0, 3506 1, 1 3507 }; 3508 fCopyProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType, 3509 kStatic_GrAccessPattern, vdata)); 3510 } 3511 if (!fCopyProgramArrayBuffer) { 3512 return false; 3513 } 3514 3515 SkASSERT(!fCopyPrograms[progIdx].fProgram); 3516 GL_CALL_RET(fCopyPrograms[progIdx].fProgram, CreateProgram()); 3517 if (!fCopyPrograms[progIdx].fProgram) { 3518 return false; 3519 } 3520 3521 const char* version = shaderCaps->versionDeclString(); 3522 GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier); 3523 GrShaderVar uTexCoordXform("u_texCoordXform", kHalf4_GrSLType, 3524 GrShaderVar::kUniform_TypeModifier); 3525 GrShaderVar uPosXform("u_posXform", kHalf4_GrSLType, GrShaderVar::kUniform_TypeModifier); 3526 GrShaderVar uTexture("u_texture", samplerType, GrShaderVar::kUniform_TypeModifier); 3527 GrShaderVar vTexCoord("v_texCoord", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier); 3528 GrShaderVar oFragColor("o_FragColor", kHalf4_GrSLType, GrShaderVar::kOut_TypeModifier); 3529 3530 SkString vshaderTxt(version); 3531 if (shaderCaps->noperspectiveInterpolationSupport()) { 3532 if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 3533 vshaderTxt.appendf("#extension %s : require\n", extension); 3534 } 3535 vTexCoord.addModifier("noperspective"); 3536 } 3537 3538 aVertex.appendDecl(shaderCaps, &vshaderTxt); 3539 vshaderTxt.append(";"); 3540 uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt); 3541 vshaderTxt.append(";"); 3542 uPosXform.appendDecl(shaderCaps, &vshaderTxt); 3543 vshaderTxt.append(";"); 3544 vTexCoord.appendDecl(shaderCaps, &vshaderTxt); 3545 vshaderTxt.append(";"); 3546 3547 vshaderTxt.append( 3548 "// Copy Program VS\n" 3549 "void main() {" 3550 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" 3551 " sk_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" 3552 " sk_Position.zw = half2(0, 1);" 3553 "}" 3554 ); 3555 3556 SkString fshaderTxt(version); 3557 if (shaderCaps->noperspectiveInterpolationSupport()) { 3558 if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 3559 fshaderTxt.appendf("#extension %s : require\n", extension); 3560 } 3561 } 3562 if (samplerType == kTextureExternalSampler_GrSLType) { 3563 fshaderTxt.appendf("#extension %s : require\n", 3564 shaderCaps->externalTextureExtensionString()); 3565 } 3566 vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier); 3567 vTexCoord.appendDecl(shaderCaps, &fshaderTxt); 3568 fshaderTxt.append(";"); 3569 uTexture.appendDecl(shaderCaps, &fshaderTxt); 3570 fshaderTxt.append(";"); 3571 fshaderTxt.appendf( 3572 "// Copy Program FS\n" 3573 "void main() {" 3574 " sk_FragColor = texture(u_texture, v_texCoord);" 3575 "}" 3576 ); 3577 3578 const char* str; 3579 GrGLint length; 3580 3581 str = vshaderTxt.c_str(); 3582 length = SkToInt(vshaderTxt.size()); 3583 SkSL::Program::Settings settings; 3584 settings.fCaps = shaderCaps; 3585 SkSL::String glsl; 3586 std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, GR_GL_VERTEX_SHADER, 3587 &str, &length, 1, settings, &glsl); 3588 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram, 3589 GR_GL_VERTEX_SHADER, glsl.c_str(), glsl.size(), 3590 &fStats, settings); 3591 SkASSERT(program->fInputs.isEmpty()); 3592 3593 str = fshaderTxt.c_str(); 3594 length = SkToInt(fshaderTxt.size()); 3595 program = GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, &str, &length, 1, settings, &glsl); 3596 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram, 3597 GR_GL_FRAGMENT_SHADER, glsl.c_str(), glsl.size(), 3598 &fStats, settings); 3599 SkASSERT(program->fInputs.isEmpty()); 3600 3601 GL_CALL(LinkProgram(fCopyPrograms[progIdx].fProgram)); 3602 3603 GL_CALL_RET(fCopyPrograms[progIdx].fTextureUniform, 3604 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texture")); 3605 GL_CALL_RET(fCopyPrograms[progIdx].fPosXformUniform, 3606 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_posXform")); 3607 GL_CALL_RET(fCopyPrograms[progIdx].fTexCoordXformUniform, 3608 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordXform")); 3609 3610 GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex")); 3611 3612 GL_CALL(DeleteShader(vshader)); 3613 GL_CALL(DeleteShader(fshader)); 3614 3615 return true; 3616 } 3617 3618 bool GrGLGpu::createMipmapProgram(int progIdx) { 3619 const bool oddWidth = SkToBool(progIdx & 0x2); 3620 const bool oddHeight = SkToBool(progIdx & 0x1); 3621 const int numTaps = (oddWidth ? 2 : 1) * (oddHeight ? 2 : 1); 3622 3623 const GrShaderCaps* shaderCaps = this->caps()->shaderCaps(); 3624 3625 SkASSERT(!fMipmapPrograms[progIdx].fProgram); 3626 GL_CALL_RET(fMipmapPrograms[progIdx].fProgram, CreateProgram()); 3627 if (!fMipmapPrograms[progIdx].fProgram) { 3628 return false; 3629 } 3630 3631 const char* version = shaderCaps->versionDeclString(); 3632 GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier); 3633 GrShaderVar uTexCoordXform("u_texCoordXform", kHalf4_GrSLType, 3634 GrShaderVar::kUniform_TypeModifier); 3635 GrShaderVar uTexture("u_texture", kTexture2DSampler_GrSLType, 3636 GrShaderVar::kUniform_TypeModifier); 3637 // We need 1, 2, or 4 texture coordinates (depending on parity of each dimension): 3638 GrShaderVar vTexCoords[] = { 3639 GrShaderVar("v_texCoord0", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier), 3640 GrShaderVar("v_texCoord1", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier), 3641 GrShaderVar("v_texCoord2", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier), 3642 GrShaderVar("v_texCoord3", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier), 3643 }; 3644 GrShaderVar oFragColor("o_FragColor", kHalf4_GrSLType,GrShaderVar::kOut_TypeModifier); 3645 3646 SkString vshaderTxt(version); 3647 if (shaderCaps->noperspectiveInterpolationSupport()) { 3648 if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 3649 vshaderTxt.appendf("#extension %s : require\n", extension); 3650 } 3651 vTexCoords[0].addModifier("noperspective"); 3652 vTexCoords[1].addModifier("noperspective"); 3653 vTexCoords[2].addModifier("noperspective"); 3654 vTexCoords[3].addModifier("noperspective"); 3655 } 3656 3657 aVertex.appendDecl(shaderCaps, &vshaderTxt); 3658 vshaderTxt.append(";"); 3659 uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt); 3660 vshaderTxt.append(";"); 3661 for (int i = 0; i < numTaps; ++i) { 3662 vTexCoords[i].appendDecl(shaderCaps, &vshaderTxt); 3663 vshaderTxt.append(";"); 3664 } 3665 3666 vshaderTxt.append( 3667 "// Mipmap Program VS\n" 3668 "void main() {" 3669 " sk_Position.xy = a_vertex * half2(2, 2) - half2(1, 1);" 3670 " sk_Position.zw = half2(0, 1);" 3671 ); 3672 3673 // Insert texture coordinate computation: 3674 if (oddWidth && oddHeight) { 3675 vshaderTxt.append( 3676 " v_texCoord0 = a_vertex.xy * u_texCoordXform.yw;" 3677 " v_texCoord1 = a_vertex.xy * u_texCoordXform.yw + half2(u_texCoordXform.x, 0);" 3678 " v_texCoord2 = a_vertex.xy * u_texCoordXform.yw + half2(0, u_texCoordXform.z);" 3679 " v_texCoord3 = a_vertex.xy * u_texCoordXform.yw + u_texCoordXform.xz;" 3680 ); 3681 } else if (oddWidth) { 3682 vshaderTxt.append( 3683 " v_texCoord0 = a_vertex.xy * half2(u_texCoordXform.y, 1);" 3684 " v_texCoord1 = a_vertex.xy * half2(u_texCoordXform.y, 1) + half2(u_texCoordXform.x, 0);" 3685 ); 3686 } else if (oddHeight) { 3687 vshaderTxt.append( 3688 " v_texCoord0 = a_vertex.xy * half2(1, u_texCoordXform.w);" 3689 " v_texCoord1 = a_vertex.xy * half2(1, u_texCoordXform.w) + half2(0, u_texCoordXform.z);" 3690 ); 3691 } else { 3692 vshaderTxt.append( 3693 " v_texCoord0 = a_vertex.xy;" 3694 ); 3695 } 3696 3697 vshaderTxt.append("}"); 3698 3699 SkString fshaderTxt(version); 3700 if (shaderCaps->noperspectiveInterpolationSupport()) { 3701 if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 3702 fshaderTxt.appendf("#extension %s : require\n", extension); 3703 } 3704 } 3705 for (int i = 0; i < numTaps; ++i) { 3706 vTexCoords[i].setTypeModifier(GrShaderVar::kIn_TypeModifier); 3707 vTexCoords[i].appendDecl(shaderCaps, &fshaderTxt); 3708 fshaderTxt.append(";"); 3709 } 3710 uTexture.appendDecl(shaderCaps, &fshaderTxt); 3711 fshaderTxt.append(";"); 3712 fshaderTxt.append( 3713 "// Mipmap Program FS\n" 3714 "void main() {" 3715 ); 3716 3717 if (oddWidth && oddHeight) { 3718 fshaderTxt.append( 3719 " sk_FragColor = (texture(u_texture, v_texCoord0) + " 3720 " texture(u_texture, v_texCoord1) + " 3721 " texture(u_texture, v_texCoord2) + " 3722 " texture(u_texture, v_texCoord3)) * 0.25;" 3723 ); 3724 } else if (oddWidth || oddHeight) { 3725 fshaderTxt.append( 3726 " sk_FragColor = (texture(u_texture, v_texCoord0) + " 3727 " texture(u_texture, v_texCoord1)) * 0.5;" 3728 ); 3729 } else { 3730 fshaderTxt.append( 3731 " sk_FragColor = texture(u_texture, v_texCoord0);" 3732 ); 3733 } 3734 3735 fshaderTxt.append("}"); 3736 3737 const char* str; 3738 GrGLint length; 3739 3740 str = vshaderTxt.c_str(); 3741 length = SkToInt(vshaderTxt.size()); 3742 SkSL::Program::Settings settings; 3743 settings.fCaps = shaderCaps; 3744 SkSL::String glsl; 3745 std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, GR_GL_VERTEX_SHADER, 3746 &str, &length, 1, settings, &glsl); 3747 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram, 3748 GR_GL_VERTEX_SHADER, glsl.c_str(), glsl.size(), 3749 &fStats, settings); 3750 SkASSERT(program->fInputs.isEmpty()); 3751 3752 str = fshaderTxt.c_str(); 3753 length = SkToInt(fshaderTxt.size()); 3754 program = GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, &str, &length, 1, settings, &glsl); 3755 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram, 3756 GR_GL_FRAGMENT_SHADER, glsl.c_str(), glsl.size(), 3757 &fStats, settings); 3758 SkASSERT(program->fInputs.isEmpty()); 3759 3760 GL_CALL(LinkProgram(fMipmapPrograms[progIdx].fProgram)); 3761 3762 GL_CALL_RET(fMipmapPrograms[progIdx].fTextureUniform, 3763 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texture")); 3764 GL_CALL_RET(fMipmapPrograms[progIdx].fTexCoordXformUniform, 3765 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texCoordXform")); 3766 3767 GL_CALL(BindAttribLocation(fMipmapPrograms[progIdx].fProgram, 0, "a_vertex")); 3768 3769 GL_CALL(DeleteShader(vshader)); 3770 GL_CALL(DeleteShader(fshader)); 3771 3772 return true; 3773 } 3774 3775 bool GrGLGpu::createStencilClipClearProgram() { 3776 TRACE_EVENT0("skia", TRACE_FUNC); 3777 3778 if (!fStencilClipClearArrayBuffer) { 3779 static const GrGLfloat vdata[] = {-1, -1, 1, -1, -1, 1, 1, 1}; 3780 fStencilClipClearArrayBuffer.reset(GrGLBuffer::Create( 3781 this, sizeof(vdata), kVertex_GrBufferType, kStatic_GrAccessPattern, vdata)); 3782 if (!fStencilClipClearArrayBuffer) { 3783 return false; 3784 } 3785 } 3786 3787 SkASSERT(!fStencilClipClearProgram); 3788 GL_CALL_RET(fStencilClipClearProgram, CreateProgram()); 3789 if (!fStencilClipClearProgram) { 3790 return false; 3791 } 3792 3793 GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier); 3794 const char* version = this->caps()->shaderCaps()->versionDeclString(); 3795 3796 SkString vshaderTxt(version); 3797 aVertex.appendDecl(this->caps()->shaderCaps(), &vshaderTxt); 3798 vshaderTxt.append(";"); 3799 vshaderTxt.append( 3800 "// Stencil Clip Clear Program VS\n" 3801 "void main() {" 3802 " sk_Position = float4(a_vertex.x, a_vertex.y, 0, 1);" 3803 "}"); 3804 3805 SkString fshaderTxt(version); 3806 fshaderTxt.appendf( 3807 "// Stencil Clip Clear Program FS\n" 3808 "void main() {" 3809 " sk_FragColor = half4(0);" 3810 "}"); 3811 3812 const char* str; 3813 GrGLint length; 3814 3815 str = vshaderTxt.c_str(); 3816 length = SkToInt(vshaderTxt.size()); 3817 SkSL::Program::Settings settings; 3818 settings.fCaps = this->caps()->shaderCaps(); 3819 SkSL::String glsl; 3820 std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, GR_GL_VERTEX_SHADER, 3821 &str, &length, 1, settings, &glsl); 3822 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fStencilClipClearProgram, 3823 GR_GL_VERTEX_SHADER, glsl.c_str(), glsl.size(), 3824 &fStats, settings); 3825 SkASSERT(program->fInputs.isEmpty()); 3826 3827 str = fshaderTxt.c_str(); 3828 length = SkToInt(fshaderTxt.size()); 3829 program = GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, &str, &length, 1, settings, &glsl); 3830 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fStencilClipClearProgram, 3831 GR_GL_FRAGMENT_SHADER, glsl.c_str(), glsl.size(), 3832 &fStats, settings); 3833 SkASSERT(program->fInputs.isEmpty()); 3834 3835 GL_CALL(LinkProgram(fStencilClipClearProgram)); 3836 3837 GL_CALL(BindAttribLocation(fStencilClipClearProgram, 0, "a_vertex")); 3838 3839 GL_CALL(DeleteShader(vshader)); 3840 GL_CALL(DeleteShader(fshader)); 3841 3842 return true; 3843 } 3844 3845 void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencilMask, 3846 GrRenderTarget* rt, GrSurfaceOrigin origin) { 3847 // TODO: This should swizzle the output to match dst's config, though it is a debugging 3848 // visualization. 3849 3850 this->handleDirtyContext(); 3851 if (!fStencilClipClearProgram) { 3852 if (!this->createStencilClipClearProgram()) { 3853 SkDebugf("Failed to create stencil clip clear program.\n"); 3854 return; 3855 } 3856 } 3857 3858 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget()); 3859 this->flushRenderTarget(glRT); 3860 3861 GL_CALL(UseProgram(fStencilClipClearProgram)); 3862 fHWProgramID = fStencilClipClearProgram; 3863 3864 fHWVertexArrayState.setVertexArrayID(this, 0); 3865 3866 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); 3867 attribs->enableVertexArrays(this, 1); 3868 attribs->set(this, 0, fStencilClipClearArrayBuffer.get(), kHalf2_GrVertexAttribType, 3869 2 * sizeof(GrGLfloat), 0); 3870 3871 GrXferProcessor::BlendInfo blendInfo; 3872 blendInfo.reset(); 3873 this->flushBlend(blendInfo, GrSwizzle::RGBA()); 3874 this->flushColorWrite(false); 3875 this->flushHWAAState(glRT, false, false); 3876 this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); 3877 this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); 3878 GrStencilAttachment* sb = rt->renderTargetPriv().getStencilAttachment(); 3879 // This should only be called internally when we know we have a stencil buffer. 3880 SkASSERT(sb); 3881 GrStencilSettings settings = GrStencilSettings( 3882 *GrStencilSettings::SetClipBitSettings(insideStencilMask), false, sb->bits()); 3883 this->flushStencil(settings); 3884 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); 3885 } 3886 3887 bool GrGLGpu::createClearColorProgram() { 3888 TRACE_EVENT0("skia", TRACE_FUNC); 3889 3890 if (!fClearProgramArrayBuffer) { 3891 static const GrGLfloat vdata[] = {-1, -1, 1, -1, -1, 1, 1, 1}; 3892 fClearProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType, 3893 kStatic_GrAccessPattern, vdata)); 3894 if (!fClearProgramArrayBuffer) { 3895 return false; 3896 } 3897 } 3898 3899 SkASSERT(!fClearColorProgram.fProgram); 3900 GL_CALL_RET(fClearColorProgram.fProgram, CreateProgram()); 3901 if (!fClearColorProgram.fProgram) { 3902 return false; 3903 } 3904 3905 GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier); 3906 const char* version = this->caps()->shaderCaps()->versionDeclString(); 3907 3908 SkString vshaderTxt(version); 3909 aVertex.appendDecl(this->caps()->shaderCaps(), &vshaderTxt); 3910 vshaderTxt.append(";"); 3911 vshaderTxt.append(R"( 3912 // Clear Color Program VS 3913 void main() { 3914 sk_Position = float4(a_vertex.x, a_vertex.y, 0, 1); 3915 })"); 3916 3917 GrShaderVar uColor("u_color", kHalf4_GrSLType, GrShaderVar::kUniform_TypeModifier); 3918 SkString fshaderTxt(version); 3919 uColor.appendDecl(this->caps()->shaderCaps(), &fshaderTxt); 3920 fshaderTxt.append(";"); 3921 fshaderTxt.appendf(R"( 3922 // Clear Color Program FS 3923 void main() { 3924 sk_FragColor = u_color; 3925 })"); 3926 3927 const char* str; 3928 GrGLint length; 3929 3930 str = vshaderTxt.c_str(); 3931 length = SkToInt(vshaderTxt.size()); 3932 SkSL::Program::Settings settings; 3933 settings.fCaps = this->caps()->shaderCaps(); 3934 SkSL::String glsl; 3935 GrSkSLtoGLSL(*fGLContext, GR_GL_VERTEX_SHADER, &str, &length, 1, settings, &glsl); 3936 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fClearColorProgram.fProgram, 3937 GR_GL_VERTEX_SHADER, glsl.c_str(), glsl.size(), 3938 &fStats, settings); 3939 3940 str = fshaderTxt.c_str(); 3941 length = SkToInt(fshaderTxt.size()); 3942 GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, &str, &length, 1, settings, &glsl); 3943 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fClearColorProgram.fProgram, 3944 GR_GL_FRAGMENT_SHADER, glsl.c_str(), glsl.size(), 3945 &fStats, settings); 3946 3947 GL_CALL(LinkProgram(fClearColorProgram.fProgram)); 3948 3949 GL_CALL(BindAttribLocation(fClearColorProgram.fProgram, 0, "a_vertex")); 3950 3951 GL_CALL_RET(fClearColorProgram.fColorUniform, 3952 GetUniformLocation(fClearColorProgram.fProgram, "u_color")); 3953 3954 GL_CALL(DeleteShader(vshader)); 3955 GL_CALL(DeleteShader(fshader)); 3956 3957 return true; 3958 } 3959 3960 void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, GrGLfloat r, GrGLfloat g, GrGLfloat b, 3961 GrGLfloat a, GrRenderTarget* dst, GrSurfaceOrigin origin) { 3962 if (!fClearColorProgram.fProgram) { 3963 if (!this->createClearColorProgram()) { 3964 SkDebugf("Failed to create clear color program.\n"); 3965 return; 3966 } 3967 } 3968 3969 GrGLIRect dstVP; 3970 this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget); 3971 this->flushViewport(dstVP); 3972 fHWBoundRenderTargetUniqueID.makeInvalid(); 3973 3974 GL_CALL(UseProgram(fClearColorProgram.fProgram)); 3975 fHWProgramID = fClearColorProgram.fProgram; 3976 3977 fHWVertexArrayState.setVertexArrayID(this, 0); 3978 3979 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); 3980 attribs->enableVertexArrays(this, 1); 3981 attribs->set(this, 0, fClearProgramArrayBuffer.get(), kHalf2_GrVertexAttribType, 3982 2 * sizeof(GrGLfloat), 0); 3983 3984 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(dst); 3985 this->flushScissor(clip.scissorState(), glrt->getViewport(), origin); 3986 this->flushWindowRectangles(clip.windowRectsState(), glrt, origin); 3987 3988 GL_CALL(Uniform4f(fClearColorProgram.fColorUniform, r, g, b, a)); 3989 3990 GrXferProcessor::BlendInfo blendInfo; 3991 blendInfo.reset(); 3992 this->flushBlend(blendInfo, GrSwizzle::RGBA()); 3993 this->flushColorWrite(true); 3994 this->flushHWAAState(nullptr, false, false); 3995 this->disableStencil(); 3996 if (this->glCaps().srgbWriteControl()) { 3997 this->flushFramebufferSRGB(true); 3998 } 3999 4000 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); 4001 this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst); 4002 this->didWriteToSurface(dst, origin, clip.scissorEnabled() ? &clip.scissorRect() : nullptr); 4003 } 4004 4005 bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, 4006 GrSurface* src, GrSurfaceOrigin srcOrigin, 4007 const SkIRect& srcRect, 4008 const SkIPoint& dstPoint) { 4009 GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture()); 4010 int progIdx = TextureToCopyProgramIdx(srcTex); 4011 4012 if (!fCopyPrograms[progIdx].fProgram) { 4013 if (!this->createCopyProgram(srcTex)) { 4014 SkDebugf("Failed to create copy program.\n"); 4015 return false; 4016 } 4017 } 4018 4019 int w = srcRect.width(); 4020 int h = srcRect.height(); 4021 4022 this->bindTexture(0, GrSamplerState::ClampNearest(), true, srcTex, srcOrigin); 4023 4024 GrGLIRect dstVP; 4025 this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget); 4026 this->flushViewport(dstVP); 4027 fHWBoundRenderTargetUniqueID.makeInvalid(); 4028 4029 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h); 4030 4031 GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram)); 4032 fHWProgramID = fCopyPrograms[progIdx].fProgram; 4033 4034 fHWVertexArrayState.setVertexArrayID(this, 0); 4035 4036 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); 4037 attribs->enableVertexArrays(this, 1); 4038 attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kHalf2_GrVertexAttribType, 4039 2 * sizeof(GrGLfloat), 0); 4040 4041 // dst rect edges in NDC (-1 to 1) 4042 int dw = dst->width(); 4043 int dh = dst->height(); 4044 GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f; 4045 GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f; 4046 GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f; 4047 GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f; 4048 if (kBottomLeft_GrSurfaceOrigin == dstOrigin) { 4049 dy0 = -dy0; 4050 dy1 = -dy1; 4051 } 4052 4053 GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft; 4054 GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w); 4055 GrGLfloat sy0 = (GrGLfloat)srcRect.fTop; 4056 GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h); 4057 int sw = src->width(); 4058 int sh = src->height(); 4059 if (kBottomLeft_GrSurfaceOrigin == srcOrigin) { 4060 sy0 = sh - sy0; 4061 sy1 = sh - sy1; 4062 } 4063 // src rect edges in normalized texture space (0 to 1) 4064 sx0 /= sw; 4065 sx1 /= sw; 4066 sy0 /= sh; 4067 sy1 /= sh; 4068 4069 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0)); 4070 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform, 4071 sx1 - sx0, sy1 - sy0, sx0, sy0)); 4072 GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0)); 4073 4074 GrXferProcessor::BlendInfo blendInfo; 4075 blendInfo.reset(); 4076 this->flushBlend(blendInfo, GrSwizzle::RGBA()); 4077 this->flushColorWrite(true); 4078 this->flushHWAAState(nullptr, false, false); 4079 this->disableScissor(); 4080 this->disableWindowRectangles(); 4081 this->disableStencil(); 4082 if (this->glCaps().srgbWriteControl()) { 4083 this->flushFramebufferSRGB(true); 4084 } 4085 4086 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); 4087 this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst); 4088 this->didWriteToSurface(dst, dstOrigin, &dstRect); 4089 4090 return true; 4091 } 4092 4093 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, 4094 GrSurface* src, GrSurfaceOrigin srcOrigin, 4095 const SkIRect& srcRect, 4096 const SkIPoint& dstPoint) { 4097 SkASSERT(can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this)); 4098 GrGLIRect srcVP; 4099 this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget); 4100 GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture()); 4101 SkASSERT(dstTex); 4102 // We modified the bound FBO 4103 fHWBoundRenderTargetUniqueID.makeInvalid(); 4104 GrGLIRect srcGLRect; 4105 srcGLRect.setRelativeTo(srcVP, srcRect, srcOrigin); 4106 4107 this->setScratchTextureUnit(); 4108 GL_CALL(BindTexture(dstTex->target(), dstTex->textureID())); 4109 GrGLint dstY; 4110 if (kBottomLeft_GrSurfaceOrigin == dstOrigin) { 4111 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); 4112 } else { 4113 dstY = dstPoint.fY; 4114 } 4115 GL_CALL(CopyTexSubImage2D(dstTex->target(), 0, 4116 dstPoint.fX, dstY, 4117 srcGLRect.fLeft, srcGLRect.fBottom, 4118 srcGLRect.fWidth, srcGLRect.fHeight)); 4119 this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, src); 4120 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 4121 srcRect.width(), srcRect.height()); 4122 this->didWriteToSurface(dst, dstOrigin, &dstRect); 4123 } 4124 4125 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin, 4126 GrSurface* src, GrSurfaceOrigin srcOrigin, 4127 const SkIRect& srcRect, 4128 const SkIPoint& dstPoint) { 4129 SkASSERT(can_blit_framebuffer_for_copy_surface(dst, dstOrigin, src, srcOrigin, 4130 srcRect, dstPoint, this)); 4131 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 4132 srcRect.width(), srcRect.height()); 4133 if (dst == src) { 4134 if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { 4135 return false; 4136 } 4137 } 4138 4139 GrGLIRect dstVP; 4140 GrGLIRect srcVP; 4141 this->bindSurfaceFBOForPixelOps(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget); 4142 this->bindSurfaceFBOForPixelOps(src, GR_GL_READ_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget); 4143 // We modified the bound FBO 4144 fHWBoundRenderTargetUniqueID.makeInvalid(); 4145 GrGLIRect srcGLRect; 4146 GrGLIRect dstGLRect; 4147 srcGLRect.setRelativeTo(srcVP, srcRect, srcOrigin); 4148 dstGLRect.setRelativeTo(dstVP, dstRect, dstOrigin); 4149 4150 // BlitFrameBuffer respects the scissor, so disable it. 4151 this->disableScissor(); 4152 this->disableWindowRectangles(); 4153 4154 GrGLint srcY0; 4155 GrGLint srcY1; 4156 // Does the blit need to y-mirror or not? 4157 if (srcOrigin == dstOrigin) { 4158 srcY0 = srcGLRect.fBottom; 4159 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; 4160 } else { 4161 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; 4162 srcY1 = srcGLRect.fBottom; 4163 } 4164 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, 4165 srcY0, 4166 srcGLRect.fLeft + srcGLRect.fWidth, 4167 srcY1, 4168 dstGLRect.fLeft, 4169 dstGLRect.fBottom, 4170 dstGLRect.fLeft + dstGLRect.fWidth, 4171 dstGLRect.fBottom + dstGLRect.fHeight, 4172 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 4173 this->unbindTextureFBOForPixelOps(GR_GL_DRAW_FRAMEBUFFER, dst); 4174 this->unbindTextureFBOForPixelOps(GR_GL_READ_FRAMEBUFFER, src); 4175 this->didWriteToSurface(dst, dstOrigin, &dstRect); 4176 return true; 4177 } 4178 4179 // Manual implementation of mipmap generation, to work around driver bugs w/sRGB. 4180 // Uses draw calls to do a series of downsample operations to successive mips. 4181 // If this returns false, then the calling code falls back to using glGenerateMipmap. 4182 bool GrGLGpu::generateMipmap(GrGLTexture* texture, GrSurfaceOrigin textureOrigin, 4183 bool gammaCorrect) { 4184 // Our iterative downsample requires the ability to limit which level we're sampling: 4185 if (!this->glCaps().doManualMipmapping()) { 4186 return false; 4187 } 4188 4189 // Mipmaps are only supported on 2D textures: 4190 if (GR_GL_TEXTURE_2D != texture->target()) { 4191 return false; 4192 } 4193 4194 // We need to be able to render to the texture for this to work: 4195 if (!this->glCaps().canConfigBeFBOColorAttachment(texture->config())) { 4196 return false; 4197 } 4198 4199 // If we're mipping an sRGB texture, we need to ensure FB sRGB is correct: 4200 if (GrPixelConfigIsSRGB(texture->config())) { 4201 // If we have write-control, just set the state that we want: 4202 if (this->glCaps().srgbWriteControl()) { 4203 this->flushFramebufferSRGB(gammaCorrect); 4204 } else if (!gammaCorrect) { 4205 // If we don't have write-control we can't do non-gamma-correct mipmapping: 4206 return false; 4207 } 4208 } 4209 4210 int width = texture->width(); 4211 int height = texture->height(); 4212 int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1; 4213 4214 // Define all mips, if we haven't previously done so: 4215 if (0 == texture->texturePriv().maxMipMapLevel()) { 4216 GrGLenum internalFormat; 4217 GrGLenum externalFormat; 4218 GrGLenum externalType; 4219 if (!this->glCaps().getTexImageFormats(texture->config(), texture->config(), 4220 &internalFormat, &externalFormat, &externalType)) { 4221 return false; 4222 } 4223 4224 this->unbindCpuToGpuXferBuffer(); 4225 4226 for (GrGLint level = 1; level < levelCount; ++level) { 4227 // Define the next mip: 4228 width = SkTMax(1, width / 2); 4229 height = SkTMax(1, height / 2); 4230 GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, level, internalFormat, 4231 width, height, 0, 4232 externalFormat, externalType, nullptr)); 4233 } 4234 } 4235 4236 // Create (if necessary), then bind temporary FBO: 4237 if (0 == fTempDstFBOID) { 4238 GL_CALL(GenFramebuffers(1, &fTempDstFBOID)); 4239 } 4240 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID)); 4241 fHWBoundRenderTargetUniqueID.makeInvalid(); 4242 4243 // Bind the texture, to get things configured for filtering. 4244 // We'll be changing our base level further below: 4245 this->setTextureUnit(0); 4246 this->bindTexture(0, GrSamplerState::ClampBilerp(), gammaCorrect, texture, textureOrigin); 4247 4248 // Vertex data: 4249 if (!fMipmapProgramArrayBuffer) { 4250 static const GrGLfloat vdata[] = { 4251 0, 0, 4252 0, 1, 4253 1, 0, 4254 1, 1 4255 }; 4256 fMipmapProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), 4257 kVertex_GrBufferType, 4258 kStatic_GrAccessPattern, vdata)); 4259 } 4260 if (!fMipmapProgramArrayBuffer) { 4261 return false; 4262 } 4263 4264 fHWVertexArrayState.setVertexArrayID(this, 0); 4265 4266 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); 4267 attribs->enableVertexArrays(this, 1); 4268 attribs->set(this, 0, fMipmapProgramArrayBuffer.get(), kHalf2_GrVertexAttribType, 4269 2 * sizeof(GrGLfloat), 0); 4270 4271 // Set "simple" state once: 4272 GrXferProcessor::BlendInfo blendInfo; 4273 blendInfo.reset(); 4274 this->flushBlend(blendInfo, GrSwizzle::RGBA()); 4275 this->flushColorWrite(true); 4276 this->flushHWAAState(nullptr, false, false); 4277 this->disableScissor(); 4278 this->disableWindowRectangles(); 4279 this->disableStencil(); 4280 4281 // Do all the blits: 4282 width = texture->width(); 4283 height = texture->height(); 4284 GrGLIRect viewport; 4285 viewport.fLeft = 0; 4286 viewport.fBottom = 0; 4287 for (GrGLint level = 1; level < levelCount; ++level) { 4288 // Get and bind the program for this particular downsample (filter shape can vary): 4289 int progIdx = TextureSizeToMipmapProgramIdx(width, height); 4290 if (!fMipmapPrograms[progIdx].fProgram) { 4291 if (!this->createMipmapProgram(progIdx)) { 4292 SkDebugf("Failed to create mipmap program.\n"); 4293 return false; 4294 } 4295 } 4296 GL_CALL(UseProgram(fMipmapPrograms[progIdx].fProgram)); 4297 fHWProgramID = fMipmapPrograms[progIdx].fProgram; 4298 4299 // Texcoord uniform is expected to contain (1/w, (w-1)/w, 1/h, (h-1)/h) 4300 const float invWidth = 1.0f / width; 4301 const float invHeight = 1.0f / height; 4302 GL_CALL(Uniform4f(fMipmapPrograms[progIdx].fTexCoordXformUniform, 4303 invWidth, (width - 1) * invWidth, invHeight, (height - 1) * invHeight)); 4304 GL_CALL(Uniform1i(fMipmapPrograms[progIdx].fTextureUniform, 0)); 4305 4306 // Only sample from previous mip 4307 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level - 1)); 4308 4309 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, 4310 GR_GL_TEXTURE_2D, texture->textureID(), level)); 4311 4312 width = SkTMax(1, width / 2); 4313 height = SkTMax(1, height / 2); 4314 viewport.fWidth = width; 4315 viewport.fHeight = height; 4316 this->flushViewport(viewport); 4317 4318 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); 4319 } 4320 4321 // Unbind: 4322 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, 4323 GR_GL_TEXTURE_2D, 0, 0)); 4324 4325 return true; 4326 } 4327 4328 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { 4329 SkASSERT(type); 4330 switch (type) { 4331 case kTexture_GrXferBarrierType: { 4332 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); 4333 SkASSERT(glrt->textureFBOID() != 0 && glrt->renderFBOID() != 0); 4334 if (glrt->textureFBOID() != glrt->renderFBOID()) { 4335 // The render target uses separate storage so no need for glTextureBarrier. 4336 // FIXME: The render target will resolve automatically when its texture is bound, 4337 // but we could resolve only the bounds that will be read if we do it here instead. 4338 return; 4339 } 4340 SkASSERT(this->caps()->textureBarrierSupport()); 4341 GL_CALL(TextureBarrier()); 4342 return; 4343 } 4344 case kBlend_GrXferBarrierType: 4345 SkASSERT(GrCaps::kAdvanced_BlendEquationSupport == 4346 this->caps()->blendEquationSupport()); 4347 GL_CALL(BlendBarrier()); 4348 return; 4349 default: break; // placate compiler warnings that kNone not handled 4350 } 4351 } 4352 4353 GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, 4354 GrPixelConfig config, bool /*isRT*/, 4355 GrMipMapped mipMapped) { 4356 if (!this->caps()->isConfigTexturable(config)) { 4357 return GrBackendTexture(); // invalid 4358 } 4359 4360 // Currently we don't support uploading pixel data when mipped. 4361 if (pixels && GrMipMapped::kYes == mipMapped) { 4362 return GrBackendTexture(); // invalid 4363 } 4364 4365 GrGLTextureInfo info; 4366 info.fTarget = GR_GL_TEXTURE_2D; 4367 info.fID = 0; 4368 GL_CALL(GenTextures(1, &info.fID)); 4369 GL_CALL(ActiveTexture(GR_GL_TEXTURE0)); 4370 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1)); 4371 GL_CALL(BindTexture(info.fTarget, info.fID)); 4372 fHWBoundTextureUniqueIDs[0].makeInvalid(); 4373 GL_CALL(TexParameteri(info.fTarget, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST)); 4374 GL_CALL(TexParameteri(info.fTarget, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST)); 4375 GL_CALL(TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE)); 4376 GL_CALL(TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE)); 4377 4378 GrGLenum internalFormat; 4379 GrGLenum externalFormat; 4380 GrGLenum externalType; 4381 4382 if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat, 4383 &externalType)) { 4384 return GrBackendTexture(); // invalid 4385 } 4386 4387 info.fFormat = this->glCaps().configSizedInternalFormat(config); 4388 4389 this->unbindCpuToGpuXferBuffer(); 4390 4391 // Figure out the number of mip levels. 4392 int mipLevels = 1; 4393 if (GrMipMapped::kYes == mipMapped) { 4394 mipLevels = SkMipMap::ComputeLevelCount(w, h) + 1; 4395 } 4396 4397 size_t bpp = GrBytesPerPixel(config); 4398 size_t baseLayerSize = bpp * w * h; 4399 SkAutoMalloc defaultStorage(baseLayerSize); 4400 if (!pixels) { 4401 // Fill in the texture with all zeros so we don't have random garbage 4402 pixels = defaultStorage.get(); 4403 memset(pixels, 0, baseLayerSize); 4404 } 4405 4406 int width = w; 4407 int height = h; 4408 for (int i = 0; i < mipLevels; ++i) { 4409 GL_CALL(TexImage2D(info.fTarget, i, internalFormat, width, height, 0, externalFormat, 4410 externalType, pixels)); 4411 width = SkTMax(1, width / 2); 4412 height = SkTMax(1, height / 2); 4413 } 4414 4415 // unbind the texture from the texture unit to avoid asserts 4416 GL_CALL(BindTexture(info.fTarget, 0)); 4417 4418 return GrBackendTexture(w, h, mipMapped, info); 4419 } 4420 4421 bool GrGLGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { 4422 SkASSERT(kOpenGL_GrBackend == tex.backend()); 4423 4424 const GrGLTextureInfo* info = tex.getGLTextureInfo(); 4425 if (!info) { 4426 return false; 4427 } 4428 4429 GrGLboolean result; 4430 GL_CALL_RET(result, IsTexture(info->fID)); 4431 4432 return (GR_GL_TRUE == result); 4433 } 4434 4435 void GrGLGpu::deleteTestingOnlyBackendTexture(GrBackendTexture* tex, bool abandonTexture) { 4436 SkASSERT(kOpenGL_GrBackend == tex->backend()); 4437 4438 const GrGLTextureInfo* info = tex->getGLTextureInfo(); 4439 if (info && !abandonTexture) { 4440 GrGLuint texID = info->fID; 4441 4442 GL_CALL(DeleteTextures(1, &texID)); 4443 } 4444 } 4445 4446 void GrGLGpu::resetShaderCacheForTesting() const { 4447 fProgramCache->abandon(); 4448 } 4449 4450 /////////////////////////////////////////////////////////////////////////////// 4451 4452 GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu, 4453 const GrBuffer* ibuf) { 4454 GrGLAttribArrayState* attribState; 4455 4456 if (gpu->glCaps().isCoreProfile()) { 4457 if (!fCoreProfileVertexArray) { 4458 GrGLuint arrayID; 4459 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); 4460 int attrCount = gpu->glCaps().maxVertexAttributes(); 4461 fCoreProfileVertexArray = new GrGLVertexArray(arrayID, attrCount); 4462 } 4463 if (ibuf) { 4464 attribState = fCoreProfileVertexArray->bindWithIndexBuffer(gpu, ibuf); 4465 } else { 4466 attribState = fCoreProfileVertexArray->bind(gpu); 4467 } 4468 } else { 4469 if (ibuf) { 4470 // bindBuffer implicitly binds VAO 0 when binding an index buffer. 4471 gpu->bindBuffer(kIndex_GrBufferType, ibuf); 4472 } else { 4473 this->setVertexArrayID(gpu, 0); 4474 } 4475 int attrCount = gpu->glCaps().maxVertexAttributes(); 4476 if (fDefaultVertexArrayAttribState.count() != attrCount) { 4477 fDefaultVertexArrayAttribState.resize(attrCount); 4478 } 4479 attribState = &fDefaultVertexArrayAttribState; 4480 } 4481 return attribState; 4482 } 4483 4484 bool GrGLGpu::onIsACopyNeededForTextureParams(GrTextureProxy* proxy, 4485 const GrSamplerState& textureParams, 4486 GrTextureProducer::CopyParams* copyParams, 4487 SkScalar scaleAdjust[2]) const { 4488 const GrTexture* texture = proxy->priv().peekTexture(); 4489 if (!texture) { 4490 // The only way to get and EXTERNAL or RECTANGLE texture in Ganesh is to wrap them. 4491 // In that case the proxy should already be instantiated. 4492 return false; 4493 } 4494 4495 if (textureParams.isRepeated() || GrSamplerState::Filter::kMipMap == textureParams.filter()) { 4496 const GrGLTexture* glTexture = static_cast<const GrGLTexture*>(texture); 4497 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || 4498 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { 4499 copyParams->fFilter = GrSamplerState::Filter::kNearest; 4500 copyParams->fWidth = texture->width(); 4501 copyParams->fHeight = texture->height(); 4502 return true; 4503 } 4504 } 4505 return false; 4506 } 4507 4508 void GrGLGpu::onFinishFlush(bool insertedSemaphore) { 4509 // If we inserted semaphores during the flush, we need to call GLFlush. 4510 if (insertedSemaphore) { 4511 GL_CALL(Flush()); 4512 } 4513 } 4514 4515 GrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() { 4516 SkASSERT(this->caps()->fenceSyncSupport()); 4517 GrGLsync sync; 4518 GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); 4519 GR_STATIC_ASSERT(sizeof(GrFence) >= sizeof(GrGLsync)); 4520 return (GrFence)sync; 4521 } 4522 4523 bool GrGLGpu::waitFence(GrFence fence, uint64_t timeout) { 4524 GrGLenum result; 4525 GL_CALL_RET(result, ClientWaitSync((GrGLsync)fence, GR_GL_SYNC_FLUSH_COMMANDS_BIT, timeout)); 4526 return (GR_GL_CONDITION_SATISFIED == result); 4527 } 4528 4529 void GrGLGpu::deleteFence(GrFence fence) const { 4530 this->deleteSync((GrGLsync)fence); 4531 } 4532 4533 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrGLGpu::makeSemaphore(bool isOwned) { 4534 SkASSERT(this->caps()->fenceSyncSupport()); 4535 return GrGLSemaphore::Make(this, isOwned); 4536 } 4537 4538 sk_sp<GrSemaphore> GrGLGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore, 4539 GrResourceProvider::SemaphoreWrapType wrapType, 4540 GrWrapOwnership ownership) { 4541 SkASSERT(this->caps()->fenceSyncSupport()); 4542 return GrGLSemaphore::MakeWrapped(this, semaphore.glSync(), ownership); 4543 } 4544 4545 void GrGLGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) { 4546 GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get()); 4547 4548 GrGLsync sync; 4549 GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); 4550 glSem->setSync(sync); 4551 4552 if (flush) { 4553 GL_CALL(Flush()); 4554 } 4555 } 4556 4557 void GrGLGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) { 4558 GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get()); 4559 4560 GL_CALL(WaitSync(glSem->sync(), 0, GR_GL_TIMEOUT_IGNORED)); 4561 } 4562 4563 void GrGLGpu::deleteSync(GrGLsync sync) const { 4564 GL_CALL(DeleteSync(sync)); 4565 } 4566 4567 void GrGLGpu::insertEventMarker(const char* msg) { 4568 GL_CALL(InsertEventMarker(strlen(msg), msg)); 4569 } 4570 4571 sk_sp<GrSemaphore> GrGLGpu::prepareTextureForCrossContextUsage(GrTexture* texture) { 4572 // Set up a semaphore to be signaled once the data is ready, and flush GL 4573 sk_sp<GrSemaphore> semaphore = this->makeSemaphore(true); 4574 this->insertSemaphore(semaphore, true); 4575 4576 return semaphore; 4577 } 4578 4579 int GrGLGpu::TextureToCopyProgramIdx(GrTexture* texture) { 4580 switch (texture->texturePriv().samplerType()) { 4581 case kTexture2DSampler_GrSLType: 4582 return 0; 4583 case kTexture2DRectSampler_GrSLType: 4584 return 1; 4585 case kTextureExternalSampler_GrSLType: 4586 return 2; 4587 default: 4588 SK_ABORT("Unexpected samper type"); 4589 return 0; 4590 } 4591 } 4592 4593 void GrGLGpu::onDumpJSON(SkJSONWriter* writer) const { 4594 // We are called by the base class, which has already called beginObject(). We choose to nest 4595 // all of our caps information in a named sub-object. 4596 writer->beginObject("GL GPU"); 4597 4598 const GrGLubyte* str; 4599 GL_CALL_RET(str, GetString(GR_GL_VERSION)); 4600 writer->appendString("GL_VERSION", (const char*)(str)); 4601 GL_CALL_RET(str, GetString(GR_GL_RENDERER)); 4602 writer->appendString("GL_RENDERER", (const char*)(str)); 4603 GL_CALL_RET(str, GetString(GR_GL_VENDOR)); 4604 writer->appendString("GL_VENDOR", (const char*)(str)); 4605 GL_CALL_RET(str, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 4606 writer->appendString("GL_SHADING_LANGUAGE_VERSION", (const char*)(str)); 4607 4608 writer->appendName("extensions"); 4609 glInterface()->fExtensions.dumpJSON(writer); 4610 4611 writer->endObject(); 4612 } 4613