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