• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/core/SkPixmap.h"
9 #include "include/core/SkStrokeRec.h"
10 #include "include/core/SkTypes.h"
11 #include "include/gpu/GrBackendSemaphore.h"
12 #include "include/gpu/GrBackendSurface.h"
13 #include "include/gpu/GrTypes.h"
14 #include "include/private/SkHalf.h"
15 #include "include/private/SkTemplates.h"
16 #include "include/private/SkTo.h"
17 #include "src/core/SkAutoMalloc.h"
18 #include "src/core/SkCompressedDataUtils.h"
19 #include "src/core/SkConvertPixels.h"
20 #include "src/core/SkMipMap.h"
21 #include "src/core/SkTraceEvent.h"
22 #include "src/gpu/GrContextPriv.h"
23 #include "src/gpu/GrCpuBuffer.h"
24 #include "src/gpu/GrDataUtils.h"
25 #include "src/gpu/GrFixedClip.h"
26 #include "src/gpu/GrGpuResourcePriv.h"
27 #include "src/gpu/GrMesh.h"
28 #include "src/gpu/GrPipeline.h"
29 #include "src/gpu/GrProgramInfo.h"
30 #include "src/gpu/GrRenderTargetPriv.h"
31 #include "src/gpu/GrShaderCaps.h"
32 #include "src/gpu/GrSurfaceProxyPriv.h"
33 #include "src/gpu/GrTexturePriv.h"
34 #include "src/gpu/gl/GrGLBuffer.h"
35 #include "src/gpu/gl/GrGLGpu.h"
36 #include "src/gpu/gl/GrGLOpsRenderPass.h"
37 #include "src/gpu/gl/GrGLSemaphore.h"
38 #include "src/gpu/gl/GrGLStencilAttachment.h"
39 #include "src/gpu/gl/GrGLTextureRenderTarget.h"
40 #include "src/gpu/gl/builders/GrGLShaderStringBuilder.h"
41 #include "src/sksl/SkSLCompiler.h"
42 
43 #include <cmath>
44 
45 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
46 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
47 
48 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
49     #define CLEAR_ERROR_BEFORE_ALLOC(iface)   GrGLClearErr(iface)
50     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL_NOERRCHECK(iface, call)
51     #define CHECK_ALLOC_ERROR(iface)          GR_GL_GET_ERROR(iface)
52 #else
53     #define CLEAR_ERROR_BEFORE_ALLOC(iface)
54     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL(iface, call)
55     #define CHECK_ALLOC_ERROR(iface)          GR_GL_NO_ERROR
56 #endif
57 
58 //#define USE_NSIGHT
59 
60 ///////////////////////////////////////////////////////////////////////////////
61 
62 static const GrGLenum gXfermodeEquation2Blend[] = {
63     // Basic OpenGL blend equations.
64     GR_GL_FUNC_ADD,
65     GR_GL_FUNC_SUBTRACT,
66     GR_GL_FUNC_REVERSE_SUBTRACT,
67 
68     // GL_KHR_blend_equation_advanced.
69     GR_GL_SCREEN,
70     GR_GL_OVERLAY,
71     GR_GL_DARKEN,
72     GR_GL_LIGHTEN,
73     GR_GL_COLORDODGE,
74     GR_GL_COLORBURN,
75     GR_GL_HARDLIGHT,
76     GR_GL_SOFTLIGHT,
77     GR_GL_DIFFERENCE,
78     GR_GL_EXCLUSION,
79     GR_GL_MULTIPLY,
80     GR_GL_HSL_HUE,
81     GR_GL_HSL_SATURATION,
82     GR_GL_HSL_COLOR,
83     GR_GL_HSL_LUMINOSITY,
84 
85     // Illegal... needs to map to something.
86     GR_GL_FUNC_ADD,
87 };
88 static_assert(0 == kAdd_GrBlendEquation);
89 static_assert(1 == kSubtract_GrBlendEquation);
90 static_assert(2 == kReverseSubtract_GrBlendEquation);
91 static_assert(3 == kScreen_GrBlendEquation);
92 static_assert(4 == kOverlay_GrBlendEquation);
93 static_assert(5 == kDarken_GrBlendEquation);
94 static_assert(6 == kLighten_GrBlendEquation);
95 static_assert(7 == kColorDodge_GrBlendEquation);
96 static_assert(8 == kColorBurn_GrBlendEquation);
97 static_assert(9 == kHardLight_GrBlendEquation);
98 static_assert(10 == kSoftLight_GrBlendEquation);
99 static_assert(11 == kDifference_GrBlendEquation);
100 static_assert(12 == kExclusion_GrBlendEquation);
101 static_assert(13 == kMultiply_GrBlendEquation);
102 static_assert(14 == kHSLHue_GrBlendEquation);
103 static_assert(15 == kHSLSaturation_GrBlendEquation);
104 static_assert(16 == kHSLColor_GrBlendEquation);
105 static_assert(17 == kHSLLuminosity_GrBlendEquation);
106 static_assert(SK_ARRAY_COUNT(gXfermodeEquation2Blend) == kGrBlendEquationCnt);
107 
108 static const GrGLenum gXfermodeCoeff2Blend[] = {
109     GR_GL_ZERO,
110     GR_GL_ONE,
111     GR_GL_SRC_COLOR,
112     GR_GL_ONE_MINUS_SRC_COLOR,
113     GR_GL_DST_COLOR,
114     GR_GL_ONE_MINUS_DST_COLOR,
115     GR_GL_SRC_ALPHA,
116     GR_GL_ONE_MINUS_SRC_ALPHA,
117     GR_GL_DST_ALPHA,
118     GR_GL_ONE_MINUS_DST_ALPHA,
119     GR_GL_CONSTANT_COLOR,
120     GR_GL_ONE_MINUS_CONSTANT_COLOR,
121     GR_GL_CONSTANT_ALPHA,
122     GR_GL_ONE_MINUS_CONSTANT_ALPHA,
123 
124     // extended blend coeffs
125     GR_GL_SRC1_COLOR,
126     GR_GL_ONE_MINUS_SRC1_COLOR,
127     GR_GL_SRC1_ALPHA,
128     GR_GL_ONE_MINUS_SRC1_ALPHA,
129 
130     // Illegal... needs to map to something.
131     GR_GL_ZERO,
132 };
133 
BlendCoeffReferencesConstant(GrBlendCoeff coeff)134 bool GrGLGpu::BlendCoeffReferencesConstant(GrBlendCoeff coeff) {
135     static const bool gCoeffReferencesBlendConst[] = {
136         false,
137         false,
138         false,
139         false,
140         false,
141         false,
142         false,
143         false,
144         false,
145         false,
146         true,
147         true,
148         true,
149         true,
150 
151         // extended blend coeffs
152         false,
153         false,
154         false,
155         false,
156 
157         // Illegal.
158         false,
159     };
160     return gCoeffReferencesBlendConst[coeff];
161     static_assert(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendConst));
162 
163     static_assert(0 == kZero_GrBlendCoeff);
164     static_assert(1 == kOne_GrBlendCoeff);
165     static_assert(2 == kSC_GrBlendCoeff);
166     static_assert(3 == kISC_GrBlendCoeff);
167     static_assert(4 == kDC_GrBlendCoeff);
168     static_assert(5 == kIDC_GrBlendCoeff);
169     static_assert(6 == kSA_GrBlendCoeff);
170     static_assert(7 == kISA_GrBlendCoeff);
171     static_assert(8 == kDA_GrBlendCoeff);
172     static_assert(9 == kIDA_GrBlendCoeff);
173     static_assert(10 == kConstC_GrBlendCoeff);
174     static_assert(11 == kIConstC_GrBlendCoeff);
175     static_assert(12 == kConstA_GrBlendCoeff);
176     static_assert(13 == kIConstA_GrBlendCoeff);
177 
178     static_assert(14 == kS2C_GrBlendCoeff);
179     static_assert(15 == kIS2C_GrBlendCoeff);
180     static_assert(16 == kS2A_GrBlendCoeff);
181     static_assert(17 == kIS2A_GrBlendCoeff);
182 
183     // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope
184     static_assert(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gXfermodeCoeff2Blend));
185 }
186 
187 //////////////////////////////////////////////////////////////////////////////
188 
gl_target_to_binding_index(GrGLenum target)189 static int gl_target_to_binding_index(GrGLenum target) {
190     switch (target) {
191         case GR_GL_TEXTURE_2D:
192             return 0;
193         case GR_GL_TEXTURE_RECTANGLE:
194             return 1;
195         case GR_GL_TEXTURE_EXTERNAL:
196             return 2;
197     }
198     SK_ABORT("Unexpected GL texture target.");
199 }
200 
boundID(GrGLenum target) const201 GrGpuResource::UniqueID GrGLGpu::TextureUnitBindings::boundID(GrGLenum target) const {
202     return fTargetBindings[gl_target_to_binding_index(target)].fBoundResourceID;
203 }
204 
hasBeenModified(GrGLenum target) const205 bool GrGLGpu::TextureUnitBindings::hasBeenModified(GrGLenum target) const {
206     return fTargetBindings[gl_target_to_binding_index(target)].fHasBeenModified;
207 }
208 
setBoundID(GrGLenum target,GrGpuResource::UniqueID resourceID)209 void GrGLGpu::TextureUnitBindings::setBoundID(GrGLenum target, GrGpuResource::UniqueID resourceID) {
210     int targetIndex = gl_target_to_binding_index(target);
211     fTargetBindings[targetIndex].fBoundResourceID = resourceID;
212     fTargetBindings[targetIndex].fHasBeenModified = true;
213 }
214 
invalidateForScratchUse(GrGLenum target)215 void GrGLGpu::TextureUnitBindings::invalidateForScratchUse(GrGLenum target) {
216     this->setBoundID(target, GrGpuResource::UniqueID());
217 }
218 
invalidateAllTargets(bool markUnmodified)219 void GrGLGpu::TextureUnitBindings::invalidateAllTargets(bool markUnmodified) {
220     for (auto& targetBinding : fTargetBindings) {
221         targetBinding.fBoundResourceID.makeInvalid();
222         if (markUnmodified) {
223             targetBinding.fHasBeenModified = false;
224         }
225     }
226 }
227 
228 //////////////////////////////////////////////////////////////////////////////
229 
filter_to_gl_mag_filter(GrSamplerState::Filter filter)230 static GrGLenum filter_to_gl_mag_filter(GrSamplerState::Filter filter) {
231     switch (filter) {
232         case GrSamplerState::Filter::kNearest: return GR_GL_NEAREST;
233         case GrSamplerState::Filter::kBilerp:  return GR_GL_LINEAR;
234         case GrSamplerState::Filter::kMipMap:  return GR_GL_LINEAR;
235     }
236     SK_ABORT("Unknown filter");
237 }
238 
filter_to_gl_min_filter(GrSamplerState::Filter filter)239 static GrGLenum filter_to_gl_min_filter(GrSamplerState::Filter filter) {
240     switch (filter) {
241         case GrSamplerState::Filter::kNearest: return GR_GL_NEAREST;
242         case GrSamplerState::Filter::kBilerp:  return GR_GL_LINEAR;
243         case GrSamplerState::Filter::kMipMap:  return GR_GL_LINEAR_MIPMAP_LINEAR;
244     }
245     SK_ABORT("Unknown filter");
246 }
247 
wrap_mode_to_gl_wrap(GrSamplerState::WrapMode wrapMode,const GrCaps & caps)248 static inline GrGLenum wrap_mode_to_gl_wrap(GrSamplerState::WrapMode wrapMode,
249                                             const GrCaps& caps) {
250     switch (wrapMode) {
251         case GrSamplerState::WrapMode::kClamp:        return GR_GL_CLAMP_TO_EDGE;
252         case GrSamplerState::WrapMode::kRepeat:       return GR_GL_REPEAT;
253         case GrSamplerState::WrapMode::kMirrorRepeat: return GR_GL_MIRRORED_REPEAT;
254         case GrSamplerState::WrapMode::kClampToBorder:
255             // May not be supported but should have been caught earlier
256             SkASSERT(caps.clampToBorderSupport());
257             return GR_GL_CLAMP_TO_BORDER;
258     }
259     SK_ABORT("Unknown wrap mode");
260 }
261 
262 ///////////////////////////////////////////////////////////////////////////////
263 
264 class GrGLGpu::SamplerObjectCache {
265 public:
SamplerObjectCache(GrGLGpu * gpu)266     SamplerObjectCache(GrGLGpu* gpu) : fGpu(gpu) {
267         fNumTextureUnits = fGpu->glCaps().shaderCaps()->maxFragmentSamplers();
268         fHWBoundSamplers.reset(new GrGLuint[fNumTextureUnits]);
269         std::fill_n(fHWBoundSamplers.get(), fNumTextureUnits, 0);
270         std::fill_n(fSamplers, kNumSamplers, 0);
271     }
272 
~SamplerObjectCache()273     ~SamplerObjectCache() {
274         if (!fNumTextureUnits) {
275             // We've already been abandoned.
276             return;
277         }
278         for (GrGLuint sampler : fSamplers) {
279             // The spec states that "zero" values should be silently ignored, however they still
280             // trigger GL errors on some NVIDIA platforms.
281             if (sampler) {
282                 GR_GL_CALL(fGpu->glInterface(), DeleteSamplers(1, &sampler));
283             }
284         }
285     }
286 
bindSampler(int unitIdx,GrSamplerState state)287     void bindSampler(int unitIdx, GrSamplerState state) {
288         int index = StateToIndex(state);
289         if (!fSamplers[index]) {
290             GrGLuint s;
291             GR_GL_CALL(fGpu->glInterface(), GenSamplers(1, &s));
292             if (!s) {
293                 return;
294             }
295             fSamplers[index] = s;
296             auto minFilter = filter_to_gl_min_filter(state.filter());
297             auto magFilter = filter_to_gl_mag_filter(state.filter());
298             auto wrapX = wrap_mode_to_gl_wrap(state.wrapModeX(), fGpu->glCaps());
299             auto wrapY = wrap_mode_to_gl_wrap(state.wrapModeY(), fGpu->glCaps());
300             GR_GL_CALL(fGpu->glInterface(),
301                        SamplerParameteri(s, GR_GL_TEXTURE_MIN_FILTER, minFilter));
302             GR_GL_CALL(fGpu->glInterface(),
303                        SamplerParameteri(s, GR_GL_TEXTURE_MAG_FILTER, magFilter));
304             GR_GL_CALL(fGpu->glInterface(), SamplerParameteri(s, GR_GL_TEXTURE_WRAP_S, wrapX));
305             GR_GL_CALL(fGpu->glInterface(), SamplerParameteri(s, GR_GL_TEXTURE_WRAP_T, wrapY));
306         }
307         if (fHWBoundSamplers[unitIdx] != fSamplers[index]) {
308             GR_GL_CALL(fGpu->glInterface(), BindSampler(unitIdx, fSamplers[index]));
309             fHWBoundSamplers[unitIdx] = fSamplers[index];
310         }
311     }
312 
invalidateBindings()313     void invalidateBindings() {
314         // When we have sampler support we always use samplers. So setting these to zero will cause
315         // a rebind on next usage.
316         std::fill_n(fHWBoundSamplers.get(), fNumTextureUnits, 0);
317     }
318 
abandon()319     void abandon() {
320         fHWBoundSamplers.reset();
321         fNumTextureUnits = 0;
322     }
323 
release()324     void release() {
325         if (!fNumTextureUnits) {
326             // We've already been abandoned.
327             return;
328         }
329         GR_GL_CALL(fGpu->glInterface(), DeleteSamplers(kNumSamplers, fSamplers));
330         std::fill_n(fSamplers, kNumSamplers, 0);
331         // Deleting a bound sampler implicitly binds sampler 0.
332         std::fill_n(fHWBoundSamplers.get(), fNumTextureUnits, 0);
333     }
334 
335 private:
StateToIndex(GrSamplerState state)336     static int StateToIndex(GrSamplerState state) {
337         int filter = static_cast<int>(state.filter());
338         SkASSERT(filter >= 0 && filter < 3);
339         int wrapX = static_cast<int>(state.wrapModeX());
340         SkASSERT(wrapX >= 0 && wrapX < 4);
341         int wrapY = static_cast<int>(state.wrapModeY());
342         SkASSERT(wrapY >= 0 && wrapY < 4);
343         int idx = 16 * filter + 4 * wrapX + wrapY;
344         SkASSERT(idx < kNumSamplers);
345         return idx;
346     }
347 
348     GrGLGpu* fGpu;
349     static constexpr int kNumSamplers = 48;
350     std::unique_ptr<GrGLuint[]> fHWBoundSamplers;
351     GrGLuint fSamplers[kNumSamplers];
352     int fNumTextureUnits;
353 };
354 
355 ///////////////////////////////////////////////////////////////////////////////
356 
Make(sk_sp<const GrGLInterface> interface,const GrContextOptions & options,GrContext * context)357 sk_sp<GrGpu> GrGLGpu::Make(sk_sp<const GrGLInterface> interface, const GrContextOptions& options,
358                            GrContext* context) {
359     if (!interface) {
360         interface = GrGLMakeNativeInterface();
361         // For clients that have written their own GrGLCreateNativeInterface and haven't yet updated
362         // to GrGLMakeNativeInterface.
363         if (!interface) {
364             interface = sk_ref_sp(GrGLCreateNativeInterface());
365         }
366         if (!interface) {
367             return nullptr;
368         }
369     }
370 #ifdef USE_NSIGHT
371     const_cast<GrContextOptions&>(options).fSuppressPathRendering = true;
372 #endif
373     auto glContext = GrGLContext::Make(std::move(interface), options);
374     if (!glContext) {
375         return nullptr;
376     }
377     return sk_sp<GrGpu>(new GrGLGpu(std::move(glContext), context));
378 }
379 
GrGLGpu(std::unique_ptr<GrGLContext> ctx,GrContext * context)380 GrGLGpu::GrGLGpu(std::unique_ptr<GrGLContext> ctx, GrContext* context)
381         : GrGpu(context)
382         , fGLContext(std::move(ctx))
383         , fProgramCache(new ProgramCache(this))
384         , fHWProgramID(0)
385         , fTempSrcFBOID(0)
386         , fTempDstFBOID(0)
387         , fStencilClearFBOID(0) {
388     SkASSERT(fGLContext);
389     GrGLClearErr(this->glInterface());
390     fCaps = sk_ref_sp(fGLContext->caps());
391 
392     fHWTextureUnitBindings.reset(this->numTextureUnits());
393 
394     this->hwBufferState(GrGpuBufferType::kVertex)->fGLTarget = GR_GL_ARRAY_BUFFER;
395     this->hwBufferState(GrGpuBufferType::kIndex)->fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER;
396     if (GrGLCaps::TransferBufferType::kChromium == this->glCaps().transferBufferType()) {
397         this->hwBufferState(GrGpuBufferType::kXferCpuToGpu)->fGLTarget =
398                 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM;
399         this->hwBufferState(GrGpuBufferType::kXferGpuToCpu)->fGLTarget =
400                 GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
401     } else {
402         this->hwBufferState(GrGpuBufferType::kXferCpuToGpu)->fGLTarget = GR_GL_PIXEL_UNPACK_BUFFER;
403         this->hwBufferState(GrGpuBufferType::kXferGpuToCpu)->fGLTarget = GR_GL_PIXEL_PACK_BUFFER;
404     }
405     for (int i = 0; i < kGrGpuBufferTypeCount; ++i) {
406         fHWBufferState[i].invalidate();
407     }
408     static_assert(4 == SK_ARRAY_COUNT(fHWBufferState));
409 
410     if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
411         fPathRendering.reset(new GrGLPathRendering(this));
412     }
413 
414     if (this->glCaps().samplerObjectSupport()) {
415         fSamplerObjectCache.reset(new SamplerObjectCache(this));
416     }
417 }
418 
~GrGLGpu()419 GrGLGpu::~GrGLGpu() {
420     // Ensure any GrGpuResource objects get deleted first, since they may require a working GrGLGpu
421     // to release the resources held by the objects themselves.
422     fPathRendering.reset();
423     fCopyProgramArrayBuffer.reset();
424     fMipmapProgramArrayBuffer.reset();
425 
426     fHWProgram.reset();
427     if (fHWProgramID) {
428         // detach the current program so there is no confusion on OpenGL's part
429         // that we want it to be deleted
430         GL_CALL(UseProgram(0));
431     }
432 
433     if (fTempSrcFBOID) {
434         this->deleteFramebuffer(fTempSrcFBOID);
435     }
436     if (fTempDstFBOID) {
437         this->deleteFramebuffer(fTempDstFBOID);
438     }
439     if (fStencilClearFBOID) {
440         this->deleteFramebuffer(fStencilClearFBOID);
441     }
442 
443     for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
444         if (0 != fCopyPrograms[i].fProgram) {
445             GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
446         }
447     }
448 
449     for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
450         if (0 != fMipmapPrograms[i].fProgram) {
451             GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram));
452         }
453     }
454 
455     fSamplerObjectCache.reset();
456 
457     while (!fFinishCallbacks.empty()) {
458         fFinishCallbacks.front().fCallback(fFinishCallbacks.front().fContext);
459         this->deleteSync(fFinishCallbacks.front().fSync);
460         fFinishCallbacks.pop_front();
461     }
462 }
463 
disconnect(DisconnectType type)464 void GrGLGpu::disconnect(DisconnectType type) {
465     INHERITED::disconnect(type);
466     if (DisconnectType::kCleanup == type) {
467         if (fHWProgramID) {
468             GL_CALL(UseProgram(0));
469         }
470         if (fTempSrcFBOID) {
471             this->deleteFramebuffer(fTempSrcFBOID);
472         }
473         if (fTempDstFBOID) {
474             this->deleteFramebuffer(fTempDstFBOID);
475         }
476         if (fStencilClearFBOID) {
477             this->deleteFramebuffer(fStencilClearFBOID);
478         }
479         for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
480             if (fCopyPrograms[i].fProgram) {
481                 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
482             }
483         }
484         for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
485             if (fMipmapPrograms[i].fProgram) {
486                 GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram));
487             }
488         }
489 
490         if (fSamplerObjectCache) {
491             fSamplerObjectCache->release();
492         }
493     } else {
494         if (fProgramCache) {
495             fProgramCache->abandon();
496         }
497         if (fSamplerObjectCache) {
498             fSamplerObjectCache->abandon();
499         }
500     }
501 
502     fHWProgram.reset();
503     fProgramCache.reset();
504 
505     fHWProgramID = 0;
506     fTempSrcFBOID = 0;
507     fTempDstFBOID = 0;
508     fStencilClearFBOID = 0;
509     fCopyProgramArrayBuffer.reset();
510     for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
511         fCopyPrograms[i].fProgram = 0;
512     }
513     fMipmapProgramArrayBuffer.reset();
514     for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
515         fMipmapPrograms[i].fProgram = 0;
516     }
517 
518     if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
519         this->glPathRendering()->disconnect(type);
520     }
521 
522     while (!fFinishCallbacks.empty()) {
523         fFinishCallbacks.front().fCallback(fFinishCallbacks.front().fContext);
524         if (DisconnectType::kCleanup == type) {
525             this->deleteSync(fFinishCallbacks.front().fSync);
526         }
527         fFinishCallbacks.pop_front();
528     }
529 }
530 
531 ///////////////////////////////////////////////////////////////////////////////
532 
onResetContext(uint32_t resetBits)533 void GrGLGpu::onResetContext(uint32_t resetBits) {
534     if (resetBits & kMisc_GrGLBackendState) {
535         // we don't use the zb at all
536         GL_CALL(Disable(GR_GL_DEPTH_TEST));
537         GL_CALL(DepthMask(GR_GL_FALSE));
538 
539         // We don't use face culling.
540         GL_CALL(Disable(GR_GL_CULL_FACE));
541         // We do use separate stencil. Our algorithms don't care which face is front vs. back so
542         // just set this to the default for self-consistency.
543         GL_CALL(FrontFace(GR_GL_CCW));
544 
545         this->hwBufferState(GrGpuBufferType::kXferCpuToGpu)->invalidate();
546         this->hwBufferState(GrGpuBufferType::kXferGpuToCpu)->invalidate();
547 
548         if (GR_IS_GR_GL(this->glStandard())) {
549 #ifndef USE_NSIGHT
550             // Desktop-only state that we never change
551             if (!this->glCaps().isCoreProfile()) {
552                 GL_CALL(Disable(GR_GL_POINT_SMOOTH));
553                 GL_CALL(Disable(GR_GL_LINE_SMOOTH));
554                 GL_CALL(Disable(GR_GL_POLYGON_SMOOTH));
555                 GL_CALL(Disable(GR_GL_POLYGON_STIPPLE));
556                 GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP));
557                 GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP));
558             }
559             // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a
560             // core profile. This seems like a bug since the core spec removes any mention of
561             // GL_ARB_imaging.
562             if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) {
563                 GL_CALL(Disable(GR_GL_COLOR_TABLE));
564             }
565             GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL));
566 
567             fHWWireframeEnabled = kUnknown_TriState;
568 #endif
569             // Since ES doesn't support glPointSize at all we always use the VS to
570             // set the point size
571             GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE));
572 
573         }
574 
575         if (GR_IS_GR_GL_ES(this->glStandard()) &&
576             this->glCaps().fbFetchRequiresEnablePerSample()) {
577             // The arm extension requires specifically enabling MSAA fetching per sample.
578             // On some devices this may have a perf hit.  Also multiple render targets are disabled
579             GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE));
580         }
581         fHWWriteToColor = kUnknown_TriState;
582         // we only ever use lines in hairline mode
583         GL_CALL(LineWidth(1));
584         GL_CALL(Disable(GR_GL_DITHER));
585 
586         fHWClearColor[0] = fHWClearColor[1] = fHWClearColor[2] = fHWClearColor[3] = SK_FloatNaN;
587     }
588 
589     if (resetBits & kMSAAEnable_GrGLBackendState) {
590         fMSAAEnabled = kUnknown_TriState;
591 
592         if (this->caps()->mixedSamplesSupport()) {
593             // The skia blend modes all use premultiplied alpha and therefore expect RGBA coverage
594             // modulation. This state has no effect when not rendering to a mixed sampled target.
595             GL_CALL(CoverageModulation(GR_GL_RGBA));
596         }
597 
598         fHWConservativeRasterEnabled = kUnknown_TriState;
599     }
600 
601     fHWActiveTextureUnitIdx = -1; // invalid
602     fLastPrimitiveType = static_cast<GrPrimitiveType>(-1);
603 
604     if (resetBits & kTextureBinding_GrGLBackendState) {
605         for (int s = 0; s < this->numTextureUnits(); ++s) {
606             fHWTextureUnitBindings[s].invalidateAllTargets(false);
607         }
608         if (fSamplerObjectCache) {
609             fSamplerObjectCache->invalidateBindings();
610         }
611     }
612 
613     if (resetBits & kBlend_GrGLBackendState) {
614         fHWBlendState.invalidate();
615     }
616 
617     if (resetBits & kView_GrGLBackendState) {
618         fHWScissorSettings.invalidate();
619         fHWWindowRectsState.invalidate();
620         fHWViewport.invalidate();
621     }
622 
623     if (resetBits & kStencil_GrGLBackendState) {
624         fHWStencilSettings.invalidate();
625         fHWStencilTestEnabled = kUnknown_TriState;
626     }
627 
628     // Vertex
629     if (resetBits & kVertex_GrGLBackendState) {
630         fHWVertexArrayState.invalidate();
631         this->hwBufferState(GrGpuBufferType::kVertex)->invalidate();
632         this->hwBufferState(GrGpuBufferType::kIndex)->invalidate();
633         fHWPatchVertexCount = 0;
634     }
635 
636     if (resetBits & kRenderTarget_GrGLBackendState) {
637         fHWBoundRenderTargetUniqueID.makeInvalid();
638         fHWSRGBFramebuffer = kUnknown_TriState;
639     }
640 
641     if (resetBits & kPathRendering_GrGLBackendState) {
642         if (this->caps()->shaderCaps()->pathRenderingSupport()) {
643             this->glPathRendering()->resetContext();
644         }
645     }
646 
647     // we assume these values
648     if (resetBits & kPixelStore_GrGLBackendState) {
649         if (this->caps()->writePixelsRowBytesSupport()) {
650             GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
651         }
652         if (this->glCaps().readPixelsRowBytesSupport()) {
653             GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
654         }
655         if (this->glCaps().packFlipYSupport()) {
656             GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
657         }
658     }
659 
660     if (resetBits & kProgram_GrGLBackendState) {
661         fHWProgramID = 0;
662         fHWProgram.reset();
663     }
664     ++fResetTimestampForTextureParameters;
665 }
666 
check_backend_texture(const GrBackendTexture & backendTex,const GrColorType colorType,const GrGLCaps & caps,GrGLTexture::Desc * desc,bool skipRectTexSupportCheck=false)667 static bool check_backend_texture(const GrBackendTexture& backendTex, const GrColorType colorType,
668                                   const GrGLCaps& caps, GrGLTexture::Desc* desc,
669                                   bool skipRectTexSupportCheck = false) {
670     GrGLTextureInfo info;
671     if (!backendTex.getGLTextureInfo(&info) || !info.fID || !info.fFormat) {
672         return false;
673     }
674 
675     desc->fSize = {backendTex.width(), backendTex.height()};
676     desc->fTarget = info.fTarget;
677     desc->fID = info.fID;
678     desc->fFormat = GrGLFormatFromGLEnum(info.fFormat);
679 
680     if (desc->fFormat == GrGLFormat::kUnknown) {
681         return false;
682     }
683     if (GR_GL_TEXTURE_EXTERNAL == desc->fTarget) {
684         if (!caps.shaderCaps()->externalTextureSupport()) {
685             return false;
686         }
687     } else if (GR_GL_TEXTURE_RECTANGLE == desc->fTarget) {
688         if (!caps.rectangleTextureSupport() && !skipRectTexSupportCheck) {
689             return false;
690         }
691     } else if (GR_GL_TEXTURE_2D != desc->fTarget) {
692         return false;
693     }
694     if (backendTex.isProtected()) {
695         // Not supported in GL backend at this time.
696         return false;
697     }
698 
699     return true;
700 }
701 
onWrapBackendTexture(const GrBackendTexture & backendTex,GrColorType colorType,GrWrapOwnership ownership,GrWrapCacheable cacheable,GrIOType ioType)702 sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
703                                                GrColorType colorType, GrWrapOwnership ownership,
704                                                GrWrapCacheable cacheable, GrIOType ioType) {
705     GrGLTexture::Desc desc;
706     if (!check_backend_texture(backendTex, colorType, this->glCaps(), &desc)) {
707         return nullptr;
708     }
709 
710     if (kBorrow_GrWrapOwnership == ownership) {
711         desc.fOwnership = GrBackendObjectOwnership::kBorrowed;
712     } else {
713         desc.fOwnership = GrBackendObjectOwnership::kOwned;
714     }
715 
716     GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid
717                                                             : GrMipMapsStatus::kNotAllocated;
718 
719     auto texture = GrGLTexture::MakeWrapped(this, mipMapsStatus, desc,
720                                             backendTex.getGLTextureParams(), cacheable, ioType);
721     // We don't know what parameters are already set on wrapped textures.
722     texture->textureParamsModified();
723     return std::move(texture);
724 }
725 
check_compressed_backend_texture(const GrBackendTexture & backendTex,const GrGLCaps & caps,GrGLTexture::Desc * desc,bool skipRectTexSupportCheck=false)726 static bool check_compressed_backend_texture(const GrBackendTexture& backendTex,
727                                              const GrGLCaps& caps, GrGLTexture::Desc* desc,
728                                              bool skipRectTexSupportCheck = false) {
729     GrGLTextureInfo info;
730     if (!backendTex.getGLTextureInfo(&info) || !info.fID || !info.fFormat) {
731         return false;
732     }
733 
734     desc->fSize = {backendTex.width(), backendTex.height()};
735     desc->fTarget = info.fTarget;
736     desc->fID = info.fID;
737     desc->fFormat = GrGLFormatFromGLEnum(info.fFormat);
738 
739     if (desc->fFormat == GrGLFormat::kUnknown) {
740         return false;
741     }
742 
743     if (GR_GL_TEXTURE_2D != desc->fTarget) {
744         return false;
745     }
746     if (backendTex.isProtected()) {
747         // Not supported in GL backend at this time.
748         return false;
749     }
750 
751     return true;
752 }
753 
onWrapCompressedBackendTexture(const GrBackendTexture & backendTex,GrWrapOwnership ownership,GrWrapCacheable cacheable)754 sk_sp<GrTexture> GrGLGpu::onWrapCompressedBackendTexture(const GrBackendTexture& backendTex,
755                                                          GrWrapOwnership ownership,
756                                                          GrWrapCacheable cacheable) {
757     GrGLTexture::Desc desc;
758     if (!check_compressed_backend_texture(backendTex, this->glCaps(), &desc)) {
759         return nullptr;
760     }
761 
762     if (kBorrow_GrWrapOwnership == ownership) {
763         desc.fOwnership = GrBackendObjectOwnership::kBorrowed;
764     } else {
765         desc.fOwnership = GrBackendObjectOwnership::kOwned;
766     }
767 
768     GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid
769                                                             : GrMipMapsStatus::kNotAllocated;
770 
771     auto texture = GrGLTexture::MakeWrapped(this, mipMapsStatus, desc,
772                                             backendTex.getGLTextureParams(), cacheable,
773                                             kRead_GrIOType);
774     // We don't know what parameters are already set on wrapped textures.
775     texture->textureParamsModified();
776     return std::move(texture);
777 }
778 
onWrapRenderableBackendTexture(const GrBackendTexture & backendTex,int sampleCnt,GrColorType colorType,GrWrapOwnership ownership,GrWrapCacheable cacheable)779 sk_sp<GrTexture> GrGLGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex,
780                                                          int sampleCnt,
781                                                          GrColorType colorType,
782                                                          GrWrapOwnership ownership,
783                                                          GrWrapCacheable cacheable) {
784     const GrGLCaps& caps = this->glCaps();
785 
786     GrGLTexture::Desc desc;
787     if (!check_backend_texture(backendTex, colorType, this->glCaps(), &desc)) {
788         return nullptr;
789     }
790     SkASSERT(caps.isFormatRenderable(desc.fFormat, sampleCnt));
791     SkASSERT(caps.isFormatTexturable(desc.fFormat));
792 
793     // We don't support rendering to a EXTERNAL texture.
794     if (GR_GL_TEXTURE_EXTERNAL == desc.fTarget) {
795         return nullptr;
796     }
797 
798     if (kBorrow_GrWrapOwnership == ownership) {
799         desc.fOwnership = GrBackendObjectOwnership::kBorrowed;
800     } else {
801         desc.fOwnership = GrBackendObjectOwnership::kOwned;
802     }
803 
804 
805     sampleCnt = caps.getRenderTargetSampleCount(sampleCnt, desc.fFormat);
806     SkASSERT(sampleCnt);
807 
808     GrGLRenderTarget::IDs rtIDs;
809     if (!this->createRenderTargetObjects(desc, sampleCnt, &rtIDs)) {
810         return nullptr;
811     }
812 
813     GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kDirty
814                                                             : GrMipMapsStatus::kNotAllocated;
815 
816     sk_sp<GrGLTextureRenderTarget> texRT(GrGLTextureRenderTarget::MakeWrapped(
817             this, sampleCnt, desc, backendTex.getGLTextureParams(), rtIDs, cacheable,
818             mipMapsStatus));
819     texRT->baseLevelWasBoundToFBO();
820     // We don't know what parameters are already set on wrapped textures.
821     texRT->textureParamsModified();
822     return std::move(texRT);
823 }
824 
onWrapBackendRenderTarget(const GrBackendRenderTarget & backendRT,GrColorType grColorType)825 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT,
826                                                          GrColorType grColorType) {
827     GrGLFramebufferInfo info;
828     if (!backendRT.getGLFramebufferInfo(&info)) {
829         return nullptr;
830     }
831 
832     if (backendRT.isProtected()) {
833         // Not supported in GL at this time.
834         return nullptr;
835     }
836 
837     const auto format = backendRT.getBackendFormat().asGLFormat();
838     if (!this->glCaps().isFormatRenderable(format, backendRT.sampleCnt())) {
839         return nullptr;
840     }
841 
842     GrGLRenderTarget::IDs rtIDs;
843     rtIDs.fRTFBOID = info.fFBOID;
844     rtIDs.fMSColorRenderbufferID = 0;
845     rtIDs.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
846     rtIDs.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed;
847 
848     int sampleCount = this->glCaps().getRenderTargetSampleCount(backendRT.sampleCnt(), format);
849 
850     return GrGLRenderTarget::MakeWrapped(this, backendRT.dimensions(), format, sampleCount, rtIDs,
851                                          backendRT.stencilBits());
852 }
853 
onWrapBackendTextureAsRenderTarget(const GrBackendTexture & tex,int sampleCnt,GrColorType colorType)854 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
855                                                                   int sampleCnt,
856                                                                   GrColorType colorType) {
857     GrGLTexture::Desc desc;
858     // We do not check whether texture rectangle is supported by Skia - if the caller provided us
859     // with a texture rectangle,we assume the necessary support exists.
860     if (!check_backend_texture(tex, colorType, this->glCaps(), &desc, true)) {
861         return nullptr;
862     }
863 
864     if (!this->glCaps().isFormatRenderable(desc.fFormat, sampleCnt)) {
865         return nullptr;
866     }
867 
868     const int sampleCount = this->glCaps().getRenderTargetSampleCount(sampleCnt, desc.fFormat);
869     GrGLRenderTarget::IDs rtIDs;
870     if (!this->createRenderTargetObjects(desc, sampleCount, &rtIDs)) {
871         return nullptr;
872     }
873     return GrGLRenderTarget::MakeWrapped(this, desc.fSize, desc.fFormat, sampleCount, rtIDs, 0);
874 }
875 
check_write_and_transfer_input(GrGLTexture * glTex)876 static bool check_write_and_transfer_input(GrGLTexture* glTex) {
877     if (!glTex) {
878         return false;
879     }
880 
881     // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textures
882     if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) {
883         return false;
884     }
885 
886     return true;
887 }
888 
onWritePixels(GrSurface * surface,int left,int top,int width,int height,GrColorType surfaceColorType,GrColorType srcColorType,const GrMipLevel texels[],int mipLevelCount,bool prepForTexSampling)889 bool GrGLGpu::onWritePixels(GrSurface* surface, int left, int top, int width, int height,
890                             GrColorType surfaceColorType, GrColorType srcColorType,
891                             const GrMipLevel texels[], int mipLevelCount,
892                             bool prepForTexSampling) {
893     auto glTex = static_cast<GrGLTexture*>(surface->asTexture());
894 
895     if (!check_write_and_transfer_input(glTex)) {
896         return false;
897     }
898 
899     this->bindTextureToScratchUnit(glTex->target(), glTex->textureID());
900 
901     SkASSERT(!GrGLFormatIsCompressed(glTex->format()));
902     return this->uploadTexData(glTex->format(), surfaceColorType, glTex->width(), glTex->height(),
903                                glTex->target(), left, top, width, height, srcColorType, texels,
904                                mipLevelCount);
905 }
906 
onTransferPixelsTo(GrTexture * texture,int left,int top,int width,int height,GrColorType textureColorType,GrColorType bufferColorType,GrGpuBuffer * transferBuffer,size_t offset,size_t rowBytes)907 bool GrGLGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
908                                  GrColorType textureColorType, GrColorType bufferColorType,
909                                  GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes) {
910     GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
911 
912     // Can't transfer compressed data
913     SkASSERT(!GrGLFormatIsCompressed(glTex->format()));
914 
915     if (!check_write_and_transfer_input(glTex)) {
916         return false;
917     }
918 
919     static_assert(sizeof(int) == sizeof(int32_t), "");
920     if (width <= 0 || height <= 0) {
921         return false;
922     }
923 
924     this->bindTextureToScratchUnit(glTex->target(), glTex->textureID());
925 
926     SkASSERT(!transferBuffer->isMapped());
927     SkASSERT(!transferBuffer->isCpuBuffer());
928     const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer);
929     this->bindBuffer(GrGpuBufferType::kXferCpuToGpu, glBuffer);
930 
931     SkDEBUGCODE(
932         SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
933         SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
934         SkASSERT(bounds.contains(subRect));
935     )
936 
937     size_t bpp = GrColorTypeBytesPerPixel(bufferColorType);
938     const size_t trimRowBytes = width * bpp;
939     const void* pixels = (void*)offset;
940     if (width < 0 || height < 0) {
941         return false;
942     }
943 
944     bool restoreGLRowLength = false;
945     if (trimRowBytes != rowBytes) {
946         // we should have checked for this support already
947         SkASSERT(this->glCaps().writePixelsRowBytesSupport());
948         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowBytes / bpp));
949         restoreGLRowLength = true;
950     }
951 
952     GrGLFormat textureFormat = glTex->format();
953     // External format and type come from the upload data.
954     GrGLenum externalFormat = 0;
955     GrGLenum externalType = 0;
956     this->glCaps().getTexSubImageExternalFormatAndType(
957             textureFormat, textureColorType, bufferColorType, &externalFormat, &externalType);
958     if (!externalFormat || !externalType) {
959         return false;
960     }
961 
962     GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1));
963     GL_CALL(TexSubImage2D(glTex->target(),
964                           0,
965                           left, top,
966                           width,
967                           height,
968                           externalFormat, externalType,
969                           pixels));
970 
971     if (restoreGLRowLength) {
972         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
973     }
974 
975     return true;
976 }
977 
onTransferPixelsFrom(GrSurface * surface,int left,int top,int width,int height,GrColorType surfaceColorType,GrColorType dstColorType,GrGpuBuffer * transferBuffer,size_t offset)978 bool GrGLGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
979                                    GrColorType surfaceColorType, GrColorType dstColorType,
980                                    GrGpuBuffer* transferBuffer, size_t offset) {
981     auto* glBuffer = static_cast<GrGLBuffer*>(transferBuffer);
982     this->bindBuffer(GrGpuBufferType::kXferGpuToCpu, glBuffer);
983     auto offsetAsPtr = reinterpret_cast<void*>(offset);
984     return this->readOrTransferPixelsFrom(surface, left, top, width, height, surfaceColorType,
985                                           dstColorType, offsetAsPtr, width);
986 }
987 
unbindCpuToGpuXferBuffer()988 void GrGLGpu::unbindCpuToGpuXferBuffer() {
989     auto* xferBufferState = this->hwBufferState(GrGpuBufferType::kXferCpuToGpu);
990     if (!xferBufferState->fBoundBufferUniqueID.isInvalid()) {
991         GL_CALL(BindBuffer(xferBufferState->fGLTarget, 0));
992         xferBufferState->invalidate();
993     }
994 }
995 
uploadTexData(GrGLFormat textureFormat,GrColorType textureColorType,int texWidth,int texHeight,GrGLenum target,int left,int top,int width,int height,GrColorType srcColorType,const GrMipLevel texels[],int mipLevelCount,GrMipMapsStatus * mipMapsStatus)996 bool GrGLGpu::uploadTexData(GrGLFormat textureFormat, GrColorType textureColorType, int texWidth,
997                             int texHeight, GrGLenum target, int left, int top, int width,
998                             int height, GrColorType srcColorType, const GrMipLevel texels[],
999                             int mipLevelCount, GrMipMapsStatus* mipMapsStatus) {
1000     // If we're uploading compressed data then we should be using uploadCompressedTexData
1001     SkASSERT(!GrGLFormatIsCompressed(textureFormat));
1002 
1003     SkASSERT(this->glCaps().isFormatTexturable(textureFormat));
1004     SkDEBUGCODE(
1005         SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
1006         SkIRect bounds = SkIRect::MakeWH(texWidth, texHeight);
1007         SkASSERT(bounds.contains(subRect));
1008     )
1009     SkASSERT(1 == mipLevelCount ||
1010              (0 == left && 0 == top && width == texWidth && height == texHeight));
1011 
1012     this->unbindCpuToGpuXferBuffer();
1013 
1014     const GrGLInterface* interface = this->glInterface();
1015     const GrGLCaps& caps = this->glCaps();
1016 
1017     size_t bpp = GrColorTypeBytesPerPixel(srcColorType);
1018 
1019     if (width == 0 || height == 0) {
1020         return false;
1021     }
1022 
1023     // External format and type come from the upload data.
1024     GrGLenum externalFormat;
1025     GrGLenum externalType;
1026     this->glCaps().getTexSubImageExternalFormatAndType(
1027             textureFormat, textureColorType, srcColorType, &externalFormat, &externalType);
1028     if (!externalFormat || !externalType) {
1029         return false;
1030     }
1031 
1032     /*
1033      *  Check whether to allocate a temporary buffer for flipping y or
1034      *  because our srcData has extra bytes past each row. If so, we need
1035      *  to trim those off here, since GL ES may not let us specify
1036      *  GL_UNPACK_ROW_LENGTH.
1037      */
1038     bool restoreGLRowLength = false;
1039 
1040     if (mipMapsStatus) {
1041         *mipMapsStatus = (mipLevelCount > 1) ?
1042                 GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated;
1043     }
1044 
1045     GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1));
1046 
1047     for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
1048         if (!texels[currentMipLevel].fPixels) {
1049             if (mipMapsStatus) {
1050                 *mipMapsStatus = GrMipMapsStatus::kDirty;
1051             }
1052             continue;
1053         }
1054         int twoToTheMipLevel = 1 << currentMipLevel;
1055         const int currentWidth = std::max(1, width / twoToTheMipLevel);
1056         const int currentHeight = std::max(1, height / twoToTheMipLevel);
1057         const size_t trimRowBytes = currentWidth * bpp;
1058         const size_t rowBytes = texels[currentMipLevel].fRowBytes;
1059 
1060         if (caps.writePixelsRowBytesSupport() && (rowBytes != trimRowBytes || restoreGLRowLength)) {
1061             GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
1062             GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
1063             restoreGLRowLength = true;
1064         }
1065 
1066         GL_CALL(TexSubImage2D(target, currentMipLevel, left, top, currentWidth, currentHeight,
1067                               externalFormat, externalType, texels[currentMipLevel].fPixels));
1068     }
1069     if (restoreGLRowLength) {
1070         SkASSERT(caps.writePixelsRowBytesSupport());
1071         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
1072     }
1073     return true;
1074 }
1075 
uploadCompressedTexData(GrGLFormat format,SkISize dimensions,GrMipMapped mipMapped,GrGLenum target,const void * data,size_t dataSize)1076 bool GrGLGpu::uploadCompressedTexData(GrGLFormat format,
1077                                       SkISize dimensions,
1078                                       GrMipMapped mipMapped,
1079                                       GrGLenum target,
1080                                       const void* data, size_t dataSize) {
1081     SkASSERT(format != GrGLFormat::kUnknown);
1082     const GrGLCaps& caps = this->glCaps();
1083 
1084     // We only need the internal format for compressed 2D textures.
1085     GrGLenum internalFormat = caps.getTexImageOrStorageInternalFormat(format);
1086     if (!internalFormat) {
1087         return false;
1088     }
1089 
1090     SkImage::CompressionType compressionType = GrGLFormatToCompressionType(format);
1091     SkASSERT(compressionType != SkImage::CompressionType::kNone);
1092 
1093     bool useTexStorage = caps.formatSupportsTexStorage(format);
1094 
1095     int numMipLevels = 1;
1096     if (mipMapped == GrMipMapped::kYes) {
1097         numMipLevels = SkMipMap::ComputeLevelCount(dimensions.width(), dimensions.height())+1;
1098     }
1099 
1100     // TODO: Make sure that the width and height that we pass to OpenGL
1101     // is a multiple of the block size.
1102 
1103     if (useTexStorage) {
1104         // We never resize or change formats of textures.
1105         GL_ALLOC_CALL(this->glInterface(),
1106                       TexStorage2D(target, numMipLevels, internalFormat, dimensions.width(),
1107                                    dimensions.height()));
1108         GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
1109         if (error != GR_GL_NO_ERROR) {
1110             return false;
1111         }
1112 
1113         size_t offset = 0;
1114         for (int level = 0; level < numMipLevels; ++level) {
1115 
1116             size_t levelDataSize = SkCompressedDataSize(compressionType, dimensions,
1117                                                         nullptr, false);
1118 
1119             GL_CALL(CompressedTexSubImage2D(target,
1120                                             level,
1121                                             0,  // left
1122                                             0,  // top
1123                                             dimensions.width(),
1124                                             dimensions.height(),
1125                                             internalFormat,
1126                                             SkToInt(levelDataSize),
1127                                             &((char*)data)[offset]));
1128 
1129             GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
1130             if (error != GR_GL_NO_ERROR) {
1131                 return false;
1132             }
1133 
1134             offset += levelDataSize;
1135             dimensions = {std::max(1, dimensions.width()/2), std::max(1, dimensions.height()/2)};
1136         }
1137     } else {
1138         size_t offset = 0;
1139 
1140         for (int level = 0; level < numMipLevels; ++level) {
1141             size_t levelDataSize = SkCompressedDataSize(compressionType, dimensions,
1142                                                         nullptr, false);
1143 
1144             const char* rawLevelData = &((char*)data)[offset];
1145             GL_ALLOC_CALL(this->glInterface(), CompressedTexImage2D(target,
1146                                                                     level,
1147                                                                     internalFormat,
1148                                                                     dimensions.width(),
1149                                                                     dimensions.height(),
1150                                                                     0,  // border
1151                                                                     SkToInt(levelDataSize),
1152                                                                     rawLevelData));
1153 
1154             GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
1155             if (error != GR_GL_NO_ERROR) {
1156                 return false;
1157             }
1158 
1159             offset += levelDataSize;
1160             dimensions = {std::max(1, dimensions.width()/2), std::max(1, dimensions.height()/2)};
1161         }
1162     }
1163     return true;
1164 }
1165 
renderbuffer_storage_msaa(const GrGLContext & ctx,int sampleCount,GrGLenum format,int width,int height)1166 static bool renderbuffer_storage_msaa(const GrGLContext& ctx,
1167                                       int sampleCount,
1168                                       GrGLenum format,
1169                                       int width, int height) {
1170     CLEAR_ERROR_BEFORE_ALLOC(ctx.glInterface());
1171     SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType());
1172     switch (ctx.caps()->msFBOType()) {
1173         case GrGLCaps::kStandard_MSFBOType:
1174             GL_ALLOC_CALL(ctx.glInterface(),
1175                           RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
1176                                                          sampleCount,
1177                                                          format,
1178                                                          width, height));
1179             break;
1180         case GrGLCaps::kES_Apple_MSFBOType:
1181             GL_ALLOC_CALL(ctx.glInterface(),
1182                           RenderbufferStorageMultisampleES2APPLE(GR_GL_RENDERBUFFER,
1183                                                                  sampleCount,
1184                                                                  format,
1185                                                                  width, height));
1186             break;
1187         case GrGLCaps::kES_EXT_MsToTexture_MSFBOType:
1188         case GrGLCaps::kES_IMG_MsToTexture_MSFBOType:
1189             GL_ALLOC_CALL(ctx.glInterface(),
1190                           RenderbufferStorageMultisampleES2EXT(GR_GL_RENDERBUFFER,
1191                                                                sampleCount,
1192                                                                format,
1193                                                                width, height));
1194             break;
1195         case GrGLCaps::kNone_MSFBOType:
1196             SK_ABORT("Shouldn't be here if we don't support multisampled renderbuffers.");
1197             break;
1198     }
1199     return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.glInterface()));
1200 }
1201 
createRenderTargetObjects(const GrGLTexture::Desc & desc,int sampleCount,GrGLRenderTarget::IDs * rtIDs)1202 bool GrGLGpu::createRenderTargetObjects(const GrGLTexture::Desc& desc,
1203                                         int sampleCount,
1204                                         GrGLRenderTarget::IDs* rtIDs) {
1205     rtIDs->fMSColorRenderbufferID = 0;
1206     rtIDs->fRTFBOID = 0;
1207     rtIDs->fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
1208     rtIDs->fTexFBOID = 0;
1209 
1210     GrGLenum colorRenderbufferFormat = 0; // suppress warning
1211 
1212     if (desc.fFormat == GrGLFormat::kUnknown) {
1213         goto FAILED;
1214     }
1215 
1216     if (sampleCount > 1 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
1217         goto FAILED;
1218     }
1219 
1220     GL_CALL(GenFramebuffers(1, &rtIDs->fTexFBOID));
1221     if (!rtIDs->fTexFBOID) {
1222         goto FAILED;
1223     }
1224 
1225     // If we are using multisampling we will create two FBOS. We render to one and then resolve to
1226     // the texture bound to the other. The exception is the IMG multisample extension. With this
1227     // extension the texture is multisampled when rendered to and then auto-resolves it when it is
1228     // rendered from.
1229     if (sampleCount > 1 && this->glCaps().usesMSAARenderBuffers()) {
1230         GL_CALL(GenFramebuffers(1, &rtIDs->fRTFBOID));
1231         GL_CALL(GenRenderbuffers(1, &rtIDs->fMSColorRenderbufferID));
1232         if (!rtIDs->fRTFBOID || !rtIDs->fMSColorRenderbufferID) {
1233             goto FAILED;
1234         }
1235         colorRenderbufferFormat = this->glCaps().getRenderbufferInternalFormat(desc.fFormat);
1236     } else {
1237         rtIDs->fRTFBOID = rtIDs->fTexFBOID;
1238     }
1239 
1240     // below here we may bind the FBO
1241     fHWBoundRenderTargetUniqueID.makeInvalid();
1242     if (rtIDs->fRTFBOID != rtIDs->fTexFBOID) {
1243         SkASSERT(sampleCount > 1);
1244         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rtIDs->fMSColorRenderbufferID));
1245         if (!renderbuffer_storage_msaa(*fGLContext, sampleCount, colorRenderbufferFormat,
1246                                        desc.fSize.width(), desc.fSize.height())) {
1247             goto FAILED;
1248         }
1249         this->bindFramebuffer(GR_GL_FRAMEBUFFER, rtIDs->fRTFBOID);
1250         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1251                                         GR_GL_COLOR_ATTACHMENT0,
1252                                         GR_GL_RENDERBUFFER,
1253                                         rtIDs->fMSColorRenderbufferID));
1254     }
1255     this->bindFramebuffer(GR_GL_FRAMEBUFFER, rtIDs->fTexFBOID);
1256 
1257     if (this->glCaps().usesImplicitMSAAResolve() && sampleCount > 1) {
1258         GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
1259                                                 GR_GL_COLOR_ATTACHMENT0,
1260                                                 desc.fTarget,
1261                                                 desc.fID,
1262                                                 0,
1263                                                 sampleCount));
1264     } else {
1265         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
1266                                      GR_GL_COLOR_ATTACHMENT0,
1267                                      desc.fTarget,
1268                                      desc.fID,
1269                                      0));
1270     }
1271 
1272     return true;
1273 
1274 FAILED:
1275     if (rtIDs->fMSColorRenderbufferID) {
1276         GL_CALL(DeleteRenderbuffers(1, &rtIDs->fMSColorRenderbufferID));
1277     }
1278     if (rtIDs->fRTFBOID != rtIDs->fTexFBOID) {
1279         this->deleteFramebuffer(rtIDs->fRTFBOID);
1280     }
1281     if (rtIDs->fTexFBOID) {
1282         this->deleteFramebuffer(rtIDs->fTexFBOID);
1283     }
1284     return false;
1285 }
1286 
1287 // good to set a break-point here to know when createTexture fails
return_null_texture()1288 static sk_sp<GrTexture> return_null_texture() {
1289 //    SkDEBUGFAIL("null texture");
1290     return nullptr;
1291 }
1292 
set_initial_texture_params(const GrGLInterface * interface,GrGLenum target)1293 static GrGLTextureParameters::SamplerOverriddenState set_initial_texture_params(
1294         const GrGLInterface* interface, GrGLenum target) {
1295     // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
1296     // drivers have a bug where an FBO won't be complete if it includes a
1297     // texture that is not mipmap complete (considering the filter in use).
1298     GrGLTextureParameters::SamplerOverriddenState state;
1299     state.fMinFilter = GR_GL_NEAREST;
1300     state.fMagFilter = GR_GL_NEAREST;
1301     state.fWrapS = GR_GL_CLAMP_TO_EDGE;
1302     state.fWrapT = GR_GL_CLAMP_TO_EDGE;
1303     GR_GL_CALL(interface, TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, state.fMagFilter));
1304     GR_GL_CALL(interface, TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, state.fMinFilter));
1305     GR_GL_CALL(interface, TexParameteri(target, GR_GL_TEXTURE_WRAP_S, state.fWrapS));
1306     GR_GL_CALL(interface, TexParameteri(target, GR_GL_TEXTURE_WRAP_T, state.fWrapT));
1307     return state;
1308 }
1309 
onCreateTexture(SkISize dimensions,const GrBackendFormat & format,GrRenderable renderable,int renderTargetSampleCnt,SkBudgeted budgeted,GrProtected isProtected,int mipLevelCount,uint32_t levelClearMask)1310 sk_sp<GrTexture> GrGLGpu::onCreateTexture(SkISize dimensions,
1311                                           const GrBackendFormat& format,
1312                                           GrRenderable renderable,
1313                                           int renderTargetSampleCnt,
1314                                           SkBudgeted budgeted,
1315                                           GrProtected isProtected,
1316                                           int mipLevelCount,
1317                                           uint32_t levelClearMask) {
1318     // We don't support protected textures in GL.
1319     if (isProtected == GrProtected::kYes) {
1320         return nullptr;
1321     }
1322     SkASSERT(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType() || renderTargetSampleCnt == 1);
1323 
1324     SkASSERT(mipLevelCount > 0);
1325     GrMipMapsStatus mipMapsStatus =
1326             mipLevelCount > 1 ? GrMipMapsStatus::kDirty : GrMipMapsStatus::kNotAllocated;
1327     GrGLTextureParameters::SamplerOverriddenState initialState;
1328     GrGLTexture::Desc texDesc;
1329     texDesc.fSize = dimensions;
1330     texDesc.fTarget = GR_GL_TEXTURE_2D;
1331     texDesc.fFormat = format.asGLFormat();
1332     texDesc.fOwnership = GrBackendObjectOwnership::kOwned;
1333     SkASSERT(texDesc.fFormat != GrGLFormat::kUnknown);
1334     SkASSERT(!GrGLFormatIsCompressed(texDesc.fFormat));
1335 
1336     texDesc.fID = this->createTexture2D(dimensions, texDesc.fFormat, renderable, &initialState,
1337                                         mipLevelCount);
1338 
1339     if (!texDesc.fID) {
1340         return return_null_texture();
1341     }
1342 
1343     sk_sp<GrGLTexture> tex;
1344     if (renderable == GrRenderable::kYes) {
1345         // unbind the texture from the texture unit before binding it to the frame buffer
1346         GL_CALL(BindTexture(texDesc.fTarget, 0));
1347         GrGLRenderTarget::IDs rtIDDesc;
1348 
1349         if (!this->createRenderTargetObjects(texDesc, renderTargetSampleCnt, &rtIDDesc)) {
1350             GL_CALL(DeleteTextures(1, &texDesc.fID));
1351             return return_null_texture();
1352         }
1353         tex = sk_make_sp<GrGLTextureRenderTarget>(
1354                 this, budgeted, renderTargetSampleCnt, texDesc, rtIDDesc, mipMapsStatus);
1355         tex->baseLevelWasBoundToFBO();
1356     } else {
1357         tex = sk_make_sp<GrGLTexture>(this, budgeted, texDesc, mipMapsStatus);
1358     }
1359     // The non-sampler params are still at their default values.
1360     tex->parameters()->set(&initialState, GrGLTextureParameters::NonsamplerState(),
1361                            fResetTimestampForTextureParameters);
1362     if (levelClearMask) {
1363         GrGLenum externalFormat, externalType;
1364         GrColorType colorType;
1365         this->glCaps().getTexSubImageDefaultFormatTypeAndColorType(texDesc.fFormat, &externalFormat,
1366                                                                    &externalType, &colorType);
1367         if (this->glCaps().clearTextureSupport()) {
1368             for (int i = 0; i < mipLevelCount; ++i) {
1369                 if (levelClearMask & (1U << i)) {
1370                     GL_CALL(ClearTexImage(tex->textureID(), i, externalFormat, externalType,
1371                                           nullptr));
1372                 }
1373             }
1374         } else if (this->glCaps().canFormatBeFBOColorAttachment(format.asGLFormat()) &&
1375                    !this->glCaps().performColorClearsAsDraws()) {
1376             this->disableScissor();
1377             this->disableWindowRectangles();
1378             this->flushColorWrite(true);
1379             this->flushClearColor(SK_PMColor4fTRANSPARENT);
1380             for (int i = 0; i < mipLevelCount; ++i) {
1381                 if (levelClearMask & (1U << i)) {
1382                     this->bindSurfaceFBOForPixelOps(tex.get(), i, GR_GL_FRAMEBUFFER,
1383                                                     kDst_TempFBOTarget);
1384                     GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
1385                     this->unbindSurfaceFBOForPixelOps(tex.get(), i, GR_GL_FRAMEBUFFER);
1386                 }
1387             }
1388             fHWBoundRenderTargetUniqueID.makeInvalid();
1389         } else {
1390             std::unique_ptr<char[]> zeros;
1391             GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1));
1392             for (int i = 0; i < mipLevelCount; ++i) {
1393                 if (levelClearMask & (1U << i)) {
1394                     int levelWidth  = std::max(1, texDesc.fSize.width()  >> i);
1395                     int levelHeight = std::max(1, texDesc.fSize.height() >> i);
1396                     // Levels only get smaller as we proceed. Once we create a zeros use it for all
1397                     // smaller levels that need clearing.
1398                     if (!zeros) {
1399                         size_t bpp = GrColorTypeBytesPerPixel(colorType);
1400                         size_t size = levelWidth * levelHeight * bpp;
1401                         zeros.reset(new char[size]());
1402                     }
1403                     this->bindTextureToScratchUnit(GR_GL_TEXTURE_2D, tex->textureID());
1404                     GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, i, 0, 0, levelWidth, levelHeight,
1405                                           externalFormat, externalType, zeros.get()));
1406                 }
1407             }
1408         }
1409     }
1410     return std::move(tex);
1411 }
1412 
onCreateCompressedTexture(SkISize dimensions,const GrBackendFormat & format,SkBudgeted budgeted,GrMipMapped mipMapped,GrProtected isProtected,const void * data,size_t dataSize)1413 sk_sp<GrTexture> GrGLGpu::onCreateCompressedTexture(SkISize dimensions,
1414                                                     const GrBackendFormat& format,
1415                                                     SkBudgeted budgeted,
1416                                                     GrMipMapped mipMapped,
1417                                                     GrProtected isProtected,
1418                                                     const void* data, size_t dataSize) {
1419     // We don't support protected textures in GL.
1420     if (isProtected == GrProtected::kYes) {
1421         return nullptr;
1422     }
1423     GrGLTextureParameters::SamplerOverriddenState initialState;
1424     GrGLTexture::Desc desc;
1425     desc.fSize = dimensions;
1426     desc.fTarget = GR_GL_TEXTURE_2D;
1427     desc.fOwnership = GrBackendObjectOwnership::kOwned;
1428     desc.fFormat = format.asGLFormat();
1429     desc.fID = this->createCompressedTexture2D(desc.fSize, desc.fFormat,
1430                                                mipMapped, &initialState,
1431                                                data, dataSize);
1432     if (!desc.fID) {
1433         return nullptr;
1434     }
1435 
1436     // Unbind this texture from the scratch texture unit.
1437     this->bindTextureToScratchUnit(GR_GL_TEXTURE_2D, 0);
1438 
1439     GrMipMapsStatus mipMapsStatus = mipMapped == GrMipMapped::kYes
1440                                                             ? GrMipMapsStatus::kValid
1441                                                             : GrMipMapsStatus::kNotAllocated;
1442 
1443     auto tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, mipMapsStatus);
1444     // The non-sampler params are still at their default values.
1445     tex->parameters()->set(&initialState, GrGLTextureParameters::NonsamplerState(),
1446                            fResetTimestampForTextureParameters);
1447     return std::move(tex);
1448 }
1449 
onCreateCompressedBackendTexture(SkISize dimensions,const GrBackendFormat & format,GrMipMapped mipMapped,GrProtected isProtected,const BackendTextureData * data)1450 GrBackendTexture GrGLGpu::onCreateCompressedBackendTexture(SkISize dimensions,
1451                                                            const GrBackendFormat& format,
1452                                                            GrMipMapped mipMapped,
1453                                                            GrProtected isProtected,
1454                                                            const BackendTextureData* data) {
1455     // We don't support protected textures in GL.
1456     if (isProtected == GrProtected::kYes) {
1457         return {};
1458     }
1459 
1460     this->handleDirtyContext();
1461 
1462     GrGLFormat glFormat = format.asGLFormat();
1463     if (glFormat == GrGLFormat::kUnknown) {
1464         return {};
1465     }
1466 
1467     const char* rawData = nullptr;
1468     size_t rawDataSize = 0;
1469     SkAutoMalloc am;
1470 
1471     SkASSERT(!data || data->type() != BackendTextureData::Type::kPixmaps);
1472     if (data && data->type() == BackendTextureData::Type::kCompressed) {
1473         rawData = (const char*) data->compressedData();
1474         rawDataSize = data->compressedSize();
1475     } else if (data && data->type() == BackendTextureData::Type::kColor) {
1476         SkImage::CompressionType compression = GrGLFormatToCompressionType(glFormat);
1477         SkASSERT(compression != SkImage::CompressionType::kNone);
1478 
1479         rawDataSize = SkCompressedDataSize(compression, dimensions, nullptr,
1480                                            mipMapped == GrMipMapped::kYes);
1481 
1482         am.reset(rawDataSize);
1483 
1484         GrFillInCompressedData(compression, dimensions, mipMapped, (char*)am.get(), data->color());
1485 
1486         rawData = (const char*) am.get();
1487     }
1488 
1489     GrGLTextureInfo info;
1490     GrGLTextureParameters::SamplerOverriddenState initialState;
1491 
1492     info.fTarget = GR_GL_TEXTURE_2D;
1493     info.fFormat = GrGLFormatToEnum(glFormat);
1494     info.fID = this->createCompressedTexture2D(dimensions, glFormat,
1495                                                mipMapped, &initialState,
1496                                                rawData, rawDataSize);
1497     if (!info.fID) {
1498         return {};
1499     }
1500 
1501     // Unbind this texture from the scratch texture unit.
1502     this->bindTextureToScratchUnit(GR_GL_TEXTURE_2D, 0);
1503 
1504     auto parameters = sk_make_sp<GrGLTextureParameters>();
1505     // The non-sampler params are still at their default values.
1506     parameters->set(&initialState, GrGLTextureParameters::NonsamplerState(),
1507                     fResetTimestampForTextureParameters);
1508 
1509     return GrBackendTexture(dimensions.width(), dimensions.height(), mipMapped, info,
1510                             std::move(parameters));
1511 }
1512 
1513 namespace {
1514 
1515 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
1516 
get_stencil_rb_sizes(const GrGLInterface * gl,GrGLStencilAttachment::Format * format)1517 void inline get_stencil_rb_sizes(const GrGLInterface* gl,
1518                                  GrGLStencilAttachment::Format* format) {
1519 
1520     // we shouldn't ever know one size and not the other
1521     SkASSERT((kUnknownBitCount == format->fStencilBits) ==
1522              (kUnknownBitCount == format->fTotalBits));
1523     if (kUnknownBitCount == format->fStencilBits) {
1524         GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1525                                          GR_GL_RENDERBUFFER_STENCIL_SIZE,
1526                                          (GrGLint*)&format->fStencilBits);
1527         if (format->fPacked) {
1528             GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1529                                              GR_GL_RENDERBUFFER_DEPTH_SIZE,
1530                                              (GrGLint*)&format->fTotalBits);
1531             format->fTotalBits += format->fStencilBits;
1532         } else {
1533             format->fTotalBits = format->fStencilBits;
1534         }
1535     }
1536 }
1537 }
1538 
getCompatibleStencilIndex(GrGLFormat format)1539 int GrGLGpu::getCompatibleStencilIndex(GrGLFormat format) {
1540     static const int kSize = 16;
1541     SkASSERT(this->glCaps().canFormatBeFBOColorAttachment(format));
1542 
1543     if (!this->glCaps().hasStencilFormatBeenDeterminedForFormat(format)) {
1544         // Default to unsupported, set this if we find a stencil format that works.
1545         int firstWorkingStencilFormatIndex = -1;
1546 
1547         GrGLuint colorID =
1548                 this->createTexture2D({kSize, kSize}, format, GrRenderable::kYes, nullptr, 1);
1549         if (!colorID) {
1550             return -1;
1551         }
1552         // unbind the texture from the texture unit before binding it to the frame buffer
1553         GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0));
1554 
1555         // Create Framebuffer
1556         GrGLuint fb = 0;
1557         GL_CALL(GenFramebuffers(1, &fb));
1558         this->bindFramebuffer(GR_GL_FRAMEBUFFER, fb);
1559         fHWBoundRenderTargetUniqueID.makeInvalid();
1560         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
1561                                      GR_GL_COLOR_ATTACHMENT0,
1562                                      GR_GL_TEXTURE_2D,
1563                                      colorID,
1564                                      0));
1565         GrGLuint sbRBID = 0;
1566         GL_CALL(GenRenderbuffers(1, &sbRBID));
1567 
1568         // look over formats till I find a compatible one
1569         int stencilFmtCnt = this->glCaps().stencilFormats().count();
1570         if (sbRBID) {
1571             GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbRBID));
1572             for (int i = 0; i < stencilFmtCnt && sbRBID; ++i) {
1573                 const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[i];
1574                 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1575                 GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
1576                                                                        sFmt.fInternalFormat,
1577                                                                        kSize, kSize));
1578                 if (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface())) {
1579                     GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1580                                                     GR_GL_STENCIL_ATTACHMENT,
1581                                                     GR_GL_RENDERBUFFER, sbRBID));
1582                     if (sFmt.fPacked) {
1583                         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1584                                                         GR_GL_DEPTH_ATTACHMENT,
1585                                                         GR_GL_RENDERBUFFER, sbRBID));
1586                     } else {
1587                         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1588                                                         GR_GL_DEPTH_ATTACHMENT,
1589                                                         GR_GL_RENDERBUFFER, 0));
1590                     }
1591                     GrGLenum status;
1592                     GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1593                     if (status == GR_GL_FRAMEBUFFER_COMPLETE) {
1594                         firstWorkingStencilFormatIndex = i;
1595                         break;
1596                     }
1597                     GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1598                                                     GR_GL_STENCIL_ATTACHMENT,
1599                                                     GR_GL_RENDERBUFFER, 0));
1600                     if (sFmt.fPacked) {
1601                         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1602                                                         GR_GL_DEPTH_ATTACHMENT,
1603                                                         GR_GL_RENDERBUFFER, 0));
1604                     }
1605                 }
1606             }
1607             GL_CALL(DeleteRenderbuffers(1, &sbRBID));
1608         }
1609         GL_CALL(DeleteTextures(1, &colorID));
1610         this->bindFramebuffer(GR_GL_FRAMEBUFFER, 0);
1611         this->deleteFramebuffer(fb);
1612         fGLContext->caps()->setStencilFormatIndexForFormat(format, firstWorkingStencilFormatIndex);
1613     }
1614     return this->glCaps().getStencilFormatIndexForFormat(format);
1615 }
1616 
createCompressedTexture2D(SkISize dimensions,GrGLFormat format,GrMipMapped mipMapped,GrGLTextureParameters::SamplerOverriddenState * initialState,const void * data,size_t dataSize)1617 GrGLuint GrGLGpu::createCompressedTexture2D(
1618         SkISize dimensions,
1619         GrGLFormat format,
1620         GrMipMapped mipMapped,
1621         GrGLTextureParameters::SamplerOverriddenState* initialState,
1622         const void* data, size_t dataSize) {
1623     if (format == GrGLFormat::kUnknown) {
1624         return 0;
1625     }
1626     GrGLuint id = 0;
1627     GL_CALL(GenTextures(1, &id));
1628     if (!id) {
1629         return 0;
1630     }
1631 
1632     this->bindTextureToScratchUnit(GR_GL_TEXTURE_2D, id);
1633 
1634     *initialState = set_initial_texture_params(this->glInterface(), GR_GL_TEXTURE_2D);
1635 
1636     if (data) {
1637         if (!this->uploadCompressedTexData(format, dimensions, mipMapped,
1638                                            GR_GL_TEXTURE_2D, data, dataSize)) {
1639             GL_CALL(DeleteTextures(1, &id));
1640             return 0;
1641         }
1642     }
1643 
1644     return id;
1645 }
1646 
createTexture2D(SkISize dimensions,GrGLFormat format,GrRenderable renderable,GrGLTextureParameters::SamplerOverriddenState * initialState,int mipLevelCount)1647 GrGLuint GrGLGpu::createTexture2D(SkISize dimensions,
1648                                   GrGLFormat format,
1649                                   GrRenderable renderable,
1650                                   GrGLTextureParameters::SamplerOverriddenState* initialState,
1651                                   int mipLevelCount) {
1652     SkASSERT(format != GrGLFormat::kUnknown);
1653     SkASSERT(!GrGLFormatIsCompressed(format));
1654 
1655     GrGLuint id = 0;
1656     GL_CALL(GenTextures(1, &id));
1657 
1658     if (!id) {
1659         return 0;
1660     }
1661 
1662     this->bindTextureToScratchUnit(GR_GL_TEXTURE_2D, id);
1663 
1664     if (GrRenderable::kYes == renderable && this->glCaps().textureUsageSupport()) {
1665         // provides a hint about how this texture will be used
1666         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_USAGE, GR_GL_FRAMEBUFFER_ATTACHMENT));
1667     }
1668 
1669     if (initialState) {
1670         *initialState = set_initial_texture_params(this->glInterface(), GR_GL_TEXTURE_2D);
1671     } else {
1672         set_initial_texture_params(this->glInterface(), GR_GL_TEXTURE_2D);
1673     }
1674 
1675     GrGLenum internalFormat = this->glCaps().getTexImageOrStorageInternalFormat(format);
1676 
1677     bool success = false;
1678     if (internalFormat) {
1679         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1680         if (this->glCaps().formatSupportsTexStorage(format)) {
1681             GL_ALLOC_CALL(this->glInterface(),
1682                           TexStorage2D(GR_GL_TEXTURE_2D, std::max(mipLevelCount, 1), internalFormat,
1683                                        dimensions.width(), dimensions.height()));
1684             success = (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface()));
1685         } else {
1686             GrGLenum externalFormat, externalType;
1687             this->glCaps().getTexImageExternalFormatAndType(format, &externalFormat, &externalType);
1688             GrGLenum error = GR_GL_NO_ERROR;
1689             if (externalFormat && externalType) {
1690                 for (int level = 0; level < mipLevelCount && error == GR_GL_NO_ERROR; level++) {
1691                     const int twoToTheMipLevel = 1 << level;
1692                     const int currentWidth = std::max(1, dimensions.width() / twoToTheMipLevel);
1693                     const int currentHeight = std::max(1, dimensions.height() / twoToTheMipLevel);
1694                     GL_ALLOC_CALL(
1695                             this->glInterface(),
1696                             TexImage2D(GR_GL_TEXTURE_2D, level, internalFormat, currentWidth,
1697                                        currentHeight, 0, externalFormat, externalType, nullptr));
1698                     error = CHECK_ALLOC_ERROR(this->glInterface());
1699                 }
1700                 success = (GR_GL_NO_ERROR == error);
1701             }
1702         }
1703     }
1704     if (success) {
1705         return id;
1706     }
1707     GL_CALL(DeleteTextures(1, &id));
1708     return 0;
1709 }
1710 
createStencilAttachmentForRenderTarget(const GrRenderTarget * rt,int width,int height,int numStencilSamples)1711 GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(
1712         const GrRenderTarget* rt, int width, int height, int numStencilSamples) {
1713     SkASSERT(width >= rt->width());
1714     SkASSERT(height >= rt->height());
1715 
1716     GrGLStencilAttachment::IDDesc sbDesc;
1717 
1718     int sIdx = this->getCompatibleStencilIndex(rt->backendFormat().asGLFormat());
1719     if (sIdx < 0) {
1720         return nullptr;
1721     }
1722 
1723     if (!sbDesc.fRenderbufferID) {
1724         GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID));
1725     }
1726     if (!sbDesc.fRenderbufferID) {
1727         return nullptr;
1728     }
1729     GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID));
1730     const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx];
1731     CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1732     // we do this "if" so that we don't call the multisample
1733     // version on a GL that doesn't have an MSAA extension.
1734     if (numStencilSamples > 1) {
1735         SkAssertResult(renderbuffer_storage_msaa(*fGLContext,
1736                                                  numStencilSamples,
1737                                                  sFmt.fInternalFormat,
1738                                                  width, height));
1739     } else {
1740         GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
1741                                                                sFmt.fInternalFormat,
1742                                                                width, height));
1743         SkASSERT(GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface()));
1744     }
1745     fStats.incStencilAttachmentCreates();
1746     // After sized formats we attempt an unsized format and take
1747     // whatever sizes GL gives us. In that case we query for the size.
1748     GrGLStencilAttachment::Format format = sFmt;
1749     get_stencil_rb_sizes(this->glInterface(), &format);
1750     GrGLStencilAttachment* stencil = new GrGLStencilAttachment(this,
1751                                                                sbDesc,
1752                                                                width,
1753                                                                height,
1754                                                                numStencilSamples,
1755                                                                format);
1756     return stencil;
1757 }
1758 
1759 ////////////////////////////////////////////////////////////////////////////////
1760 
onCreateBuffer(size_t size,GrGpuBufferType intendedType,GrAccessPattern accessPattern,const void * data)1761 sk_sp<GrGpuBuffer> GrGLGpu::onCreateBuffer(size_t size, GrGpuBufferType intendedType,
1762                                            GrAccessPattern accessPattern, const void* data) {
1763     return GrGLBuffer::Make(this, size, intendedType, accessPattern, data);
1764 }
1765 
flushScissor(const GrScissorState & scissorState,int rtWidth,int rtHeight,GrSurfaceOrigin rtOrigin)1766 void GrGLGpu::flushScissor(const GrScissorState& scissorState, int rtWidth, int rtHeight,
1767                            GrSurfaceOrigin rtOrigin) {
1768     if (scissorState.enabled()) {
1769         auto scissor = GrNativeRect::MakeRelativeTo(rtOrigin, rtHeight, scissorState.rect());
1770         if (fHWScissorSettings.fRect != scissor) {
1771             GL_CALL(Scissor(scissor.fX, scissor.fY, scissor.fWidth, scissor.fHeight));
1772             fHWScissorSettings.fRect = scissor;
1773         }
1774         if (kYes_TriState != fHWScissorSettings.fEnabled) {
1775             GL_CALL(Enable(GR_GL_SCISSOR_TEST));
1776             fHWScissorSettings.fEnabled = kYes_TriState;
1777         }
1778         return;
1779     }
1780 
1781     // See fall through note above
1782     this->disableScissor();
1783 }
1784 
flushWindowRectangles(const GrWindowRectsState & windowState,const GrGLRenderTarget * rt,GrSurfaceOrigin origin)1785 void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
1786                                     const GrGLRenderTarget* rt, GrSurfaceOrigin origin) {
1787 #ifndef USE_NSIGHT
1788     typedef GrWindowRectsState::Mode Mode;
1789     SkASSERT(!windowState.enabled() || rt->renderFBOID()); // Window rects can't be used on-screen.
1790     SkASSERT(windowState.numWindows() <= this->caps()->maxWindowRectangles());
1791 
1792     if (!this->caps()->maxWindowRectangles() ||
1793         fHWWindowRectsState.knownEqualTo(origin, rt->width(), rt->height(), windowState)) {
1794         return;
1795     }
1796 
1797     // This is purely a workaround for a spurious warning generated by gcc. Otherwise the above
1798     // assert would be sufficient. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=5912
1799     int numWindows = std::min(windowState.numWindows(), int(GrWindowRectangles::kMaxWindows));
1800     SkASSERT(windowState.numWindows() == numWindows);
1801 
1802     GrNativeRect glwindows[GrWindowRectangles::kMaxWindows];
1803     const SkIRect* skwindows = windowState.windows().data();
1804     for (int i = 0; i < numWindows; ++i) {
1805         glwindows[i].setRelativeTo(origin, rt->height(), skwindows[i]);
1806     }
1807 
1808     GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE;
1809     GL_CALL(WindowRectangles(glmode, numWindows, glwindows->asInts()));
1810 
1811     fHWWindowRectsState.set(origin, rt->width(), rt->height(), windowState);
1812 #endif
1813 }
1814 
disableWindowRectangles()1815 void GrGLGpu::disableWindowRectangles() {
1816 #ifndef USE_NSIGHT
1817     if (!this->caps()->maxWindowRectangles() || fHWWindowRectsState.knownDisabled()) {
1818         return;
1819     }
1820     GL_CALL(WindowRectangles(GR_GL_EXCLUSIVE, 0, nullptr));
1821     fHWWindowRectsState.setDisabled();
1822 #endif
1823 }
1824 
flushGLState(GrRenderTarget * renderTarget,const GrProgramInfo & programInfo)1825 bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& programInfo) {
1826     this->handleDirtyContext();
1827 
1828     if (GrPrimitiveType::kPatches == programInfo.primitiveType()) {
1829         this->flushPatchVertexCount(programInfo.tessellationPatchVertexCount());
1830     }
1831 
1832     sk_sp<GrGLProgram> program(fProgramCache->findOrCreateProgram(renderTarget, programInfo));
1833     if (!program) {
1834         GrCapsDebugf(this->caps(), "Failed to create program!\n");
1835         return false;
1836     }
1837 
1838     this->flushProgram(std::move(program));
1839 
1840     // Swizzle the blend to match what the shader will output.
1841     this->flushBlendAndColorWrite(programInfo.pipeline().getXferProcessor().getBlendInfo(),
1842                                   programInfo.pipeline().outputSwizzle());
1843 
1844     fHWProgram->updateUniforms(renderTarget, programInfo);
1845     if (!programInfo.hasDynamicPrimProcTextures()) {
1846         auto* primProcTextures = (programInfo.hasFixedPrimProcTextures())
1847                 ? programInfo.fixedPrimProcTextures() : nullptr;
1848         fHWProgram->bindTextures(programInfo.primProc(), programInfo.pipeline(), primProcTextures);
1849     }
1850 
1851     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
1852     GrStencilSettings stencil;
1853     if (programInfo.pipeline().isStencilEnabled()) {
1854         SkASSERT(glRT->renderTargetPriv().getStencilAttachment());
1855         stencil.reset(*programInfo.pipeline().getUserStencil(),
1856                       programInfo.pipeline().hasStencilClip(),
1857                       glRT->renderTargetPriv().numStencilBits());
1858     }
1859     this->flushStencil(stencil, programInfo.origin());
1860     if (programInfo.pipeline().isScissorEnabled()) {
1861         static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
1862         GrScissorState state(programInfo.fixedDynamicState() ? programInfo.fixedScissor()
1863                                                              : kBogusScissor);
1864         this->flushScissor(state, glRT->width(), glRT->height(), programInfo.origin());
1865     } else {
1866         this->disableScissor();
1867     }
1868     this->flushWindowRectangles(programInfo.pipeline().getWindowRectsState(),
1869                                 glRT, programInfo.origin());
1870     this->flushHWAAState(glRT, programInfo.pipeline().isHWAntialiasState());
1871     this->flushConservativeRasterState(programInfo.pipeline().usesConservativeRaster());
1872     this->flushWireframeState(programInfo.pipeline().isWireframe());
1873 
1874     // This must come after textures are flushed because a texture may need
1875     // to be msaa-resolved (which will modify bound FBO state).
1876     this->flushRenderTarget(glRT);
1877 
1878     return true;
1879 }
1880 
flushProgram(sk_sp<GrGLProgram> program)1881 void GrGLGpu::flushProgram(sk_sp<GrGLProgram> program) {
1882     if (!program) {
1883         fHWProgram.reset();
1884         fHWProgramID = 0;
1885         return;
1886     }
1887     SkASSERT((program == fHWProgram) == (fHWProgramID == program->programID()));
1888     if (program == fHWProgram) {
1889         return;
1890     }
1891     auto id = program->programID();
1892     SkASSERT(id);
1893     GL_CALL(UseProgram(id));
1894     fHWProgram = std::move(program);
1895     fHWProgramID = id;
1896 }
1897 
flushProgram(GrGLuint id)1898 void GrGLGpu::flushProgram(GrGLuint id) {
1899     SkASSERT(id);
1900     if (fHWProgramID == id) {
1901         SkASSERT(!fHWProgram);
1902         return;
1903     }
1904     fHWProgram.reset();
1905     GL_CALL(UseProgram(id));
1906     fHWProgramID = id;
1907 }
1908 
setupGeometry(const GrBuffer * indexBuffer,const GrBuffer * vertexBuffer,int baseVertex,const GrBuffer * instanceBuffer,int baseInstance,GrPrimitiveRestart enablePrimitiveRestart)1909 void GrGLGpu::setupGeometry(const GrBuffer* indexBuffer,
1910                             const GrBuffer* vertexBuffer,
1911                             int baseVertex,
1912                             const GrBuffer* instanceBuffer,
1913                             int baseInstance,
1914                             GrPrimitiveRestart enablePrimitiveRestart) {
1915     SkASSERT((enablePrimitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer);
1916 
1917     GrGLAttribArrayState* attribState;
1918     if (indexBuffer) {
1919         SkASSERT(indexBuffer->isCpuBuffer() ||
1920                  !static_cast<const GrGpuBuffer*>(indexBuffer)->isMapped());
1921         attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
1922     } else {
1923         attribState = fHWVertexArrayState.bindInternalVertexArray(this);
1924     }
1925 
1926     int numAttribs = fHWProgram->numVertexAttributes() + fHWProgram->numInstanceAttributes();
1927     attribState->enableVertexArrays(this, numAttribs, enablePrimitiveRestart);
1928 
1929     if (int vertexStride = fHWProgram->vertexStride()) {
1930         SkASSERT(vertexBuffer);
1931         SkASSERT(vertexBuffer->isCpuBuffer() ||
1932                  !static_cast<const GrGpuBuffer*>(vertexBuffer)->isMapped());
1933         size_t bufferOffset = baseVertex * static_cast<size_t>(vertexStride);
1934         for (int i = 0; i < fHWProgram->numVertexAttributes(); ++i) {
1935             const auto& attrib = fHWProgram->vertexAttribute(i);
1936             static constexpr int kDivisor = 0;
1937             attribState->set(this, attrib.fLocation, vertexBuffer, attrib.fCPUType, attrib.fGPUType,
1938                              vertexStride, bufferOffset + attrib.fOffset, kDivisor);
1939         }
1940     }
1941     if (int instanceStride = fHWProgram->instanceStride()) {
1942         SkASSERT(instanceBuffer);
1943         SkASSERT(instanceBuffer->isCpuBuffer() ||
1944                  !static_cast<const GrGpuBuffer*>(instanceBuffer)->isMapped());
1945         size_t bufferOffset = baseInstance * static_cast<size_t>(instanceStride);
1946         int attribIdx = fHWProgram->numVertexAttributes();
1947         for (int i = 0; i < fHWProgram->numInstanceAttributes(); ++i, ++attribIdx) {
1948             const auto& attrib = fHWProgram->instanceAttribute(i);
1949             static constexpr int kDivisor = 1;
1950             attribState->set(this, attrib.fLocation, instanceBuffer, attrib.fCPUType,
1951                              attrib.fGPUType, instanceStride, bufferOffset + attrib.fOffset,
1952                              kDivisor);
1953         }
1954     }
1955 }
1956 
bindBuffer(GrGpuBufferType type,const GrBuffer * buffer)1957 GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) {
1958     this->handleDirtyContext();
1959 
1960     // Index buffer state is tied to the vertex array.
1961     if (GrGpuBufferType::kIndex == type) {
1962         this->bindVertexArray(0);
1963     }
1964 
1965     auto* bufferState = this->hwBufferState(type);
1966     if (buffer->isCpuBuffer()) {
1967         if (!bufferState->fBufferZeroKnownBound) {
1968             GL_CALL(BindBuffer(bufferState->fGLTarget, 0));
1969             bufferState->fBufferZeroKnownBound = true;
1970             bufferState->fBoundBufferUniqueID.makeInvalid();
1971         }
1972     } else if (static_cast<const GrGpuBuffer*>(buffer)->uniqueID() !=
1973                bufferState->fBoundBufferUniqueID) {
1974         const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(buffer);
1975         GL_CALL(BindBuffer(bufferState->fGLTarget, glBuffer->bufferID()));
1976         bufferState->fBufferZeroKnownBound = false;
1977         bufferState->fBoundBufferUniqueID = glBuffer->uniqueID();
1978     }
1979 
1980     return bufferState->fGLTarget;
1981 }
disableScissor()1982 void GrGLGpu::disableScissor() {
1983     if (kNo_TriState != fHWScissorSettings.fEnabled) {
1984         GL_CALL(Disable(GR_GL_SCISSOR_TEST));
1985         fHWScissorSettings.fEnabled = kNo_TriState;
1986         return;
1987     }
1988 }
1989 
clear(const GrFixedClip & clip,const SkPMColor4f & color,GrRenderTarget * target,GrSurfaceOrigin origin)1990 void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color,
1991                     GrRenderTarget* target, GrSurfaceOrigin origin) {
1992     // parent class should never let us get here with no RT
1993     SkASSERT(target);
1994     SkASSERT(!this->caps()->performColorClearsAsDraws());
1995     SkASSERT(!clip.scissorEnabled() || !this->caps()->performPartialClearsAsDraws());
1996 
1997     this->handleDirtyContext();
1998 
1999     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
2000 
2001     if (clip.scissorEnabled()) {
2002         this->flushRenderTarget(glRT, origin, clip.scissorRect());
2003     } else {
2004         this->flushRenderTarget(glRT);
2005     }
2006     this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin);
2007     this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
2008     this->flushColorWrite(true);
2009     this->flushClearColor(color);
2010     GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
2011 }
2012 
clearStencil(GrRenderTarget * target,int clearValue)2013 void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) {
2014     SkASSERT(!this->caps()->performStencilClearsAsDraws());
2015 
2016     if (!target) {
2017         return;
2018     }
2019 
2020     // This should only be called internally when we know we have a stencil buffer.
2021     SkASSERT(target->renderTargetPriv().getStencilAttachment());
2022 
2023     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
2024     this->flushRenderTargetNoColorWrites(glRT);
2025 
2026     this->disableScissor();
2027     this->disableWindowRectangles();
2028 
2029     GL_CALL(StencilMask(0xffffffff));
2030     GL_CALL(ClearStencil(clearValue));
2031     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
2032     fHWStencilSettings.invalidate();
2033 }
2034 
use_tiled_rendering(const GrGLCaps & glCaps,const GrOpsRenderPass::StencilLoadAndStoreInfo & stencilLoadStore)2035 static bool use_tiled_rendering(const GrGLCaps& glCaps,
2036                                 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore) {
2037     // Only use the tiled rendering extension if we can explicitly clear and discard the stencil.
2038     // Otherwise it's faster to just not use it.
2039     return glCaps.tiledRenderingSupport() && GrLoadOp::kClear == stencilLoadStore.fLoadOp &&
2040            GrStoreOp::kDiscard == stencilLoadStore.fStoreOp;
2041 }
2042 
beginCommandBuffer(GrRenderTarget * rt,const SkIRect & bounds,GrSurfaceOrigin origin,const GrOpsRenderPass::LoadAndStoreInfo & colorLoadStore,const GrOpsRenderPass::StencilLoadAndStoreInfo & stencilLoadStore)2043 void GrGLGpu::beginCommandBuffer(GrRenderTarget* rt, const SkIRect& bounds, GrSurfaceOrigin origin,
2044                                  const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
2045                                  const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore) {
2046     SkASSERT(!fIsExecutingCommandBuffer_DebugOnly);
2047 
2048     this->handleDirtyContext();
2049 
2050     auto glRT = static_cast<GrGLRenderTarget*>(rt);
2051     this->flushRenderTarget(glRT);
2052     SkDEBUGCODE(fIsExecutingCommandBuffer_DebugOnly = true);
2053 
2054     if (use_tiled_rendering(this->glCaps(), stencilLoadStore)) {
2055         auto nativeBounds = GrNativeRect::MakeRelativeTo(origin, glRT->height(), bounds);
2056         GrGLbitfield preserveMask = (GrLoadOp::kLoad == colorLoadStore.fLoadOp)
2057                 ? GR_GL_COLOR_BUFFER_BIT0 : GR_GL_NONE;
2058         SkASSERT(GrLoadOp::kLoad != stencilLoadStore.fLoadOp);  // Handled by use_tiled_rendering().
2059         GL_CALL(StartTiling(nativeBounds.fX, nativeBounds.fY, nativeBounds.fWidth,
2060                             nativeBounds.fHeight, preserveMask));
2061     }
2062 
2063     GrGLbitfield clearMask = 0;
2064     if (GrLoadOp::kClear == colorLoadStore.fLoadOp) {
2065         SkASSERT(!this->caps()->performColorClearsAsDraws());
2066         this->flushClearColor(colorLoadStore.fClearColor);
2067         this->flushColorWrite(true);
2068         clearMask |= GR_GL_COLOR_BUFFER_BIT;
2069     }
2070     if (GrLoadOp::kClear == stencilLoadStore.fLoadOp) {
2071         SkASSERT(!this->caps()->performStencilClearsAsDraws());
2072         GL_CALL(StencilMask(0xffffffff));
2073         GL_CALL(ClearStencil(0));
2074         clearMask |= GR_GL_STENCIL_BUFFER_BIT;
2075     }
2076     if (clearMask) {
2077         this->disableScissor();
2078         this->disableWindowRectangles();
2079         GL_CALL(Clear(clearMask));
2080     }
2081 }
2082 
endCommandBuffer(GrRenderTarget * rt,const GrOpsRenderPass::LoadAndStoreInfo & colorLoadStore,const GrOpsRenderPass::StencilLoadAndStoreInfo & stencilLoadStore)2083 void GrGLGpu::endCommandBuffer(GrRenderTarget* rt,
2084                                const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
2085                                const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore) {
2086     SkASSERT(fIsExecutingCommandBuffer_DebugOnly);
2087 
2088     this->handleDirtyContext();
2089 
2090     if (rt->uniqueID() != fHWBoundRenderTargetUniqueID) {
2091         // The framebuffer binding changed in the middle of a command buffer. We should have already
2092         // printed a warning during onFBOChanged.
2093         return;
2094     }
2095 
2096     if (GrGLCaps::kNone_InvalidateFBType != this->glCaps().invalidateFBType()) {
2097         auto glRT = static_cast<GrGLRenderTarget*>(rt);
2098 
2099         SkSTArray<2, GrGLenum> discardAttachments;
2100         if (GrStoreOp::kDiscard == colorLoadStore.fStoreOp) {
2101             discardAttachments.push_back(
2102                     (0 == glRT->renderFBOID()) ? GR_GL_COLOR : GR_GL_COLOR_ATTACHMENT0);
2103         }
2104         if (GrStoreOp::kDiscard == stencilLoadStore.fStoreOp) {
2105             discardAttachments.push_back(
2106                     (0 == glRT->renderFBOID()) ? GR_GL_STENCIL : GR_GL_STENCIL_ATTACHMENT);
2107         }
2108 
2109         if (!discardAttachments.empty()) {
2110             if (GrGLCaps::kInvalidate_InvalidateFBType == this->glCaps().invalidateFBType()) {
2111                 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, discardAttachments.count(),
2112                                               discardAttachments.begin()));
2113             } else {
2114                 SkASSERT(GrGLCaps::kDiscard_InvalidateFBType == this->glCaps().invalidateFBType());
2115                 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, discardAttachments.count(),
2116                                            discardAttachments.begin()));
2117             }
2118         }
2119     }
2120 
2121     if (use_tiled_rendering(this->glCaps(), stencilLoadStore)) {
2122         GrGLbitfield preserveMask = (GrStoreOp::kStore == colorLoadStore.fStoreOp)
2123                 ? GR_GL_COLOR_BUFFER_BIT0 : GR_GL_NONE;
2124         // Handled by use_tiled_rendering().
2125         SkASSERT(GrStoreOp::kStore != stencilLoadStore.fStoreOp);
2126         GL_CALL(EndTiling(preserveMask));
2127     }
2128 
2129     SkDEBUGCODE(fIsExecutingCommandBuffer_DebugOnly = false);
2130 }
2131 
clearStencilClip(const GrFixedClip & clip,bool insideStencilMask,GrRenderTarget * target,GrSurfaceOrigin origin)2132 void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
2133                                bool insideStencilMask,
2134                                GrRenderTarget* target, GrSurfaceOrigin origin) {
2135     SkASSERT(target);
2136     SkASSERT(!this->caps()->performStencilClearsAsDraws());
2137     this->handleDirtyContext();
2138 
2139     GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
2140     if (!sb) {
2141         // We should only get here if we marked a proxy as requiring a SB. However,
2142         // the SB creation could later fail. Likely clipping is going to go awry now.
2143         return;
2144     }
2145 
2146     GrGLint stencilBitCount =  sb->bits();
2147 #if 0
2148     SkASSERT(stencilBitCount > 0);
2149     GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
2150 #else
2151     // we could just clear the clip bit but when we go through
2152     // ANGLE a partial stencil mask will cause clears to be
2153     // turned into draws. Our contract on GrOpsTask says that
2154     // changing the clip between stencil passes may or may not
2155     // zero the client's clip bits. So we just clear the whole thing.
2156     static const GrGLint clipStencilMask  = ~0;
2157 #endif
2158     GrGLint value;
2159     if (insideStencilMask) {
2160         value = (1 << (stencilBitCount - 1));
2161     } else {
2162         value = 0;
2163     }
2164     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
2165     this->flushRenderTargetNoColorWrites(glRT);
2166 
2167     this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin);
2168     this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
2169 
2170     GL_CALL(StencilMask((uint32_t) clipStencilMask));
2171     GL_CALL(ClearStencil(value));
2172     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
2173     fHWStencilSettings.invalidate();
2174 }
2175 
readOrTransferPixelsFrom(GrSurface * surface,int left,int top,int width,int height,GrColorType surfaceColorType,GrColorType dstColorType,void * offsetOrPtr,int rowWidthInPixels)2176 bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
2177                                        GrColorType surfaceColorType, GrColorType dstColorType,
2178                                        void* offsetOrPtr, int rowWidthInPixels) {
2179     SkASSERT(surface);
2180 
2181     auto format = surface->backendFormat().asGLFormat();
2182     GrGLRenderTarget* renderTarget = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
2183     if (!renderTarget && !this->glCaps().isFormatRenderable(format, 1)) {
2184         return false;
2185     }
2186     GrGLenum externalFormat = 0;
2187     GrGLenum externalType = 0;
2188     this->glCaps().getReadPixelsFormat(surface->backendFormat().asGLFormat(),
2189                                        surfaceColorType,
2190                                        dstColorType,
2191                                        &externalFormat,
2192                                        &externalType);
2193     if (!externalFormat || !externalType) {
2194         return false;
2195     }
2196 
2197     if (renderTarget) {
2198         if (renderTarget->numSamples() <= 1 ||
2199             renderTarget->renderFBOID() == renderTarget->textureFBOID()) {  // Also catches FBO 0.
2200             SkASSERT(!renderTarget->requiresManualMSAAResolve());
2201             this->flushRenderTargetNoColorWrites(renderTarget);
2202         } else if (GrGLRenderTarget::kUnresolvableFBOID == renderTarget->textureFBOID()) {
2203             SkASSERT(!renderTarget->requiresManualMSAAResolve());
2204             return false;
2205         } else {
2206             SkASSERT(renderTarget->requiresManualMSAAResolve());
2207             // we don't track the state of the READ FBO ID.
2208             this->bindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID());
2209         }
2210     } else {
2211         // Use a temporary FBO.
2212         this->bindSurfaceFBOForPixelOps(surface, 0, GR_GL_FRAMEBUFFER, kSrc_TempFBOTarget);
2213         fHWBoundRenderTargetUniqueID.makeInvalid();
2214     }
2215 
2216     // the read rect is viewport-relative
2217     GrNativeRect readRect = {left, top, width, height};
2218 
2219     // determine if GL can read using the passed rowBytes or if we need a scratch buffer.
2220     if (rowWidthInPixels != width) {
2221         SkASSERT(this->glCaps().readPixelsRowBytesSupport());
2222         GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowWidthInPixels));
2223     }
2224     GL_CALL(PixelStorei(GR_GL_PACK_ALIGNMENT, 1));
2225 
2226     bool reattachStencil = false;
2227     if (this->glCaps().detachStencilFromMSAABuffersBeforeReadPixels() &&
2228         renderTarget &&
2229         renderTarget->renderTargetPriv().getStencilAttachment() &&
2230         renderTarget->numSamples() > 1) {
2231         // Fix Adreno devices that won't read from MSAA framebuffers with stencil attached
2232         reattachStencil = true;
2233         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT,
2234                                         GR_GL_RENDERBUFFER, 0));
2235     }
2236 
2237     GL_CALL(ReadPixels(readRect.fX, readRect.fY, readRect.fWidth, readRect.fHeight,
2238                        externalFormat, externalType, offsetOrPtr));
2239 
2240     if (reattachStencil) {
2241         GrGLStencilAttachment* stencilAttachment = static_cast<GrGLStencilAttachment*>(
2242                 renderTarget->renderTargetPriv().getStencilAttachment());
2243         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT,
2244                                         GR_GL_RENDERBUFFER, stencilAttachment->renderbufferID()));
2245     }
2246 
2247     if (rowWidthInPixels != width) {
2248         SkASSERT(this->glCaps().readPixelsRowBytesSupport());
2249         GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
2250     }
2251 
2252     if (!renderTarget) {
2253         this->unbindSurfaceFBOForPixelOps(surface, 0, GR_GL_FRAMEBUFFER);
2254     }
2255     return true;
2256 }
2257 
onReadPixels(GrSurface * surface,int left,int top,int width,int height,GrColorType surfaceColorType,GrColorType dstColorType,void * buffer,size_t rowBytes)2258 bool GrGLGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
2259                            GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
2260                            size_t rowBytes) {
2261     SkASSERT(surface);
2262 
2263     size_t bytesPerPixel = GrColorTypeBytesPerPixel(dstColorType);
2264 
2265     // GL_PACK_ROW_LENGTH is in terms of pixels not bytes.
2266     int rowPixelWidth;
2267 
2268     if (rowBytes == SkToSizeT(width * bytesPerPixel)) {
2269         rowPixelWidth = width;
2270     } else {
2271         SkASSERT(!(rowBytes % bytesPerPixel));
2272         rowPixelWidth = rowBytes / bytesPerPixel;
2273     }
2274     return this->readOrTransferPixelsFrom(surface, left, top, width, height, surfaceColorType,
2275                                           dstColorType, buffer, rowPixelWidth);
2276 }
2277 
getOpsRenderPass(GrRenderTarget * rt,GrSurfaceOrigin origin,const SkIRect & bounds,const GrOpsRenderPass::LoadAndStoreInfo & colorInfo,const GrOpsRenderPass::StencilLoadAndStoreInfo & stencilInfo,const SkTArray<GrSurfaceProxy *,true> & sampledProxies)2278 GrOpsRenderPass* GrGLGpu::getOpsRenderPass(
2279         GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
2280         const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
2281         const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
2282         const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
2283     if (!fCachedOpsRenderPass) {
2284         fCachedOpsRenderPass.reset(new GrGLOpsRenderPass(this));
2285     }
2286 
2287     fCachedOpsRenderPass->set(rt, bounds, origin, colorInfo, stencilInfo);
2288     return fCachedOpsRenderPass.get();
2289 }
2290 
flushRenderTarget(GrGLRenderTarget * target,GrSurfaceOrigin origin,const SkIRect & bounds)2291 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, GrSurfaceOrigin origin,
2292                                 const SkIRect& bounds) {
2293     this->flushRenderTargetNoColorWrites(target);
2294     this->didWriteToSurface(target, origin, &bounds);
2295 }
2296 
flushRenderTarget(GrGLRenderTarget * target)2297 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target) {
2298     this->flushRenderTargetNoColorWrites(target);
2299     this->didWriteToSurface(target, kTopLeft_GrSurfaceOrigin, nullptr);
2300 }
2301 
flushRenderTargetNoColorWrites(GrGLRenderTarget * target)2302 void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target) {
2303     SkASSERT(target);
2304     GrGpuResource::UniqueID rtID = target->uniqueID();
2305     if (fHWBoundRenderTargetUniqueID != rtID) {
2306         this->bindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID());
2307 #ifdef SK_DEBUG
2308         // don't do this check in Chromium -- this is causing
2309         // lots of repeated command buffer flushes when the compositor is
2310         // rendering with Ganesh, which is really slow; even too slow for
2311         // Debug mode.
2312         if (kChromium_GrGLDriver != this->glContext().driver()) {
2313             GrGLenum status;
2314             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
2315             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
2316                 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x\n", status);
2317             }
2318         }
2319 #endif
2320         fHWBoundRenderTargetUniqueID = rtID;
2321         this->flushViewport(target->width(), target->height());
2322     }
2323 
2324     if (this->glCaps().srgbWriteControl()) {
2325         this->flushFramebufferSRGB(this->caps()->isFormatSRGB(target->backendFormat()));
2326     }
2327 
2328     if (this->glCaps().shouldQueryImplementationReadSupport(target->format())) {
2329         GrGLint format;
2330         GrGLint type;
2331         GR_GL_GetIntegerv(this->glInterface(), GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
2332         GR_GL_GetIntegerv(this->glInterface(), GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
2333         this->glCaps().didQueryImplementationReadSupport(target->format(), format, type);
2334     }
2335 }
2336 
flushFramebufferSRGB(bool enable)2337 void GrGLGpu::flushFramebufferSRGB(bool enable) {
2338     if (enable && kYes_TriState != fHWSRGBFramebuffer) {
2339         GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB));
2340         fHWSRGBFramebuffer = kYes_TriState;
2341     } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) {
2342         GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB));
2343         fHWSRGBFramebuffer = kNo_TriState;
2344     }
2345 }
2346 
flushViewport(int width,int height)2347 void GrGLGpu::flushViewport(int width, int height) {
2348     GrNativeRect viewport = {0, 0, width, height};
2349     if (fHWViewport != viewport) {
2350         GL_CALL(Viewport(viewport.fX, viewport.fY, viewport.fWidth, viewport.fHeight));
2351         fHWViewport = viewport;
2352     }
2353 }
2354 
2355 #define SWAP_PER_DRAW 0
2356 
2357 #if SWAP_PER_DRAW
2358     #if defined(SK_BUILD_FOR_MAC)
2359         #include <AGL/agl.h>
2360     #elif defined(SK_BUILD_FOR_WIN)
2361         #include <gl/GL.h>
SwapBuf()2362         void SwapBuf() {
2363             DWORD procID = GetCurrentProcessId();
2364             HWND hwnd = GetTopWindow(GetDesktopWindow());
2365             while(hwnd) {
2366                 DWORD wndProcID = 0;
2367                 GetWindowThreadProcessId(hwnd, &wndProcID);
2368                 if(wndProcID == procID) {
2369                     SwapBuffers(GetDC(hwnd));
2370                 }
2371                 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
2372             }
2373          }
2374     #endif
2375 #endif
2376 
drawMeshes(GrRenderTarget * renderTarget,const GrProgramInfo & programInfo,const GrMesh meshes[],int meshCount)2377 void GrGLGpu::drawMeshes(GrRenderTarget* renderTarget, const GrProgramInfo& programInfo,
2378                          const GrMesh meshes[], int meshCount) {
2379     SkASSERT(meshCount); // guaranteed by GrOpsRenderPass::draw
2380 
2381     bool hasDynamicScissors = programInfo.hasDynamicScissors();
2382     bool hasDynamicPrimProcTextures = programInfo.hasDynamicPrimProcTextures();
2383 
2384     for (int m = 0; m < meshCount; ++m) {
2385         if (auto barrierType = programInfo.pipeline().xferBarrierType(renderTarget->asTexture(),
2386                                                                       *this->caps())) {
2387             this->xferBarrier(renderTarget, barrierType);
2388         }
2389 
2390         if (hasDynamicScissors) {
2391             GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
2392             this->flushScissor(GrScissorState(programInfo.dynamicScissor(m)),
2393                                glRT->width(), glRT->height(), programInfo.origin());
2394         }
2395         if (hasDynamicPrimProcTextures) {
2396             fHWProgram->bindTextures(programInfo.primProc(), programInfo.pipeline(),
2397                                      programInfo.dynamicPrimProcTextures(m));
2398         }
2399         if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
2400             GrIsPrimTypeLines(programInfo.primitiveType()) &&
2401             !GrIsPrimTypeLines(fLastPrimitiveType)) {
2402             GL_CALL(Enable(GR_GL_CULL_FACE));
2403             GL_CALL(Disable(GR_GL_CULL_FACE));
2404         }
2405         meshes[m].sendToGpu(programInfo.primitiveType(), this);
2406         fLastPrimitiveType = programInfo.primitiveType();
2407     }
2408 
2409 #if SWAP_PER_DRAW
2410     glFlush();
2411     #if defined(SK_BUILD_FOR_MAC)
2412         aglSwapBuffers(aglGetCurrentContext());
2413         int set_a_break_pt_here = 9;
2414         aglSwapBuffers(aglGetCurrentContext());
2415     #elif defined(SK_BUILD_FOR_WIN)
2416         SwapBuf();
2417         int set_a_break_pt_here = 9;
2418         SwapBuf();
2419     #endif
2420 #endif
2421 }
2422 
gr_primitive_type_to_gl_mode(GrPrimitiveType primitiveType)2423 static GrGLenum gr_primitive_type_to_gl_mode(GrPrimitiveType primitiveType) {
2424     switch (primitiveType) {
2425         case GrPrimitiveType::kTriangles:
2426             return GR_GL_TRIANGLES;
2427         case GrPrimitiveType::kTriangleStrip:
2428             return GR_GL_TRIANGLE_STRIP;
2429         case GrPrimitiveType::kPoints:
2430             return GR_GL_POINTS;
2431         case GrPrimitiveType::kLines:
2432             return GR_GL_LINES;
2433         case GrPrimitiveType::kLineStrip:
2434             return GR_GL_LINE_STRIP;
2435         case GrPrimitiveType::kPatches:
2436             return GR_GL_PATCHES;
2437         case GrPrimitiveType::kPath:
2438             SK_ABORT("non-mesh-based GrPrimitiveType");
2439             return 0;
2440     }
2441     SK_ABORT("invalid GrPrimitiveType");
2442 }
2443 
sendArrayMeshToGpu(GrPrimitiveType primitiveType,const GrMesh & mesh,int vertexCount,int baseVertex)2444 void GrGLGpu::sendArrayMeshToGpu(GrPrimitiveType primitiveType, const GrMesh& mesh, int vertexCount,
2445                                  int baseVertex) {
2446     const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2447     if (this->glCaps().drawArraysBaseVertexIsBroken()) {
2448         this->setupGeometry(nullptr, mesh.vertexBuffer(), baseVertex, nullptr, 0,
2449                             GrPrimitiveRestart::kNo);
2450         GL_CALL(DrawArrays(glPrimType, 0, vertexCount));
2451     } else {
2452         this->setupGeometry(nullptr, mesh.vertexBuffer(), 0, nullptr, 0, GrPrimitiveRestart::kNo);
2453         GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount));
2454     }
2455     fStats.incNumDraws();
2456 }
2457 
element_ptr(const GrBuffer * indexBuffer,int baseIndex)2458 static const GrGLvoid* element_ptr(const GrBuffer* indexBuffer, int baseIndex) {
2459     size_t baseOffset = baseIndex * sizeof(uint16_t);
2460     if (indexBuffer->isCpuBuffer()) {
2461         return static_cast<const GrCpuBuffer*>(indexBuffer)->data() + baseOffset;
2462     } else {
2463         return reinterpret_cast<const GrGLvoid*>(baseOffset);
2464     }
2465 }
2466 
sendIndexedMeshToGpu(GrPrimitiveType primitiveType,const GrMesh & mesh,int indexCount,int baseIndex,uint16_t minIndexValue,uint16_t maxIndexValue,int baseVertex)2467 void GrGLGpu::sendIndexedMeshToGpu(GrPrimitiveType primitiveType, const GrMesh& mesh,
2468                                    int indexCount, int baseIndex, uint16_t minIndexValue,
2469                                    uint16_t maxIndexValue, int baseVertex) {
2470     const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2471     const GrGLvoid* elementPtr = element_ptr(mesh.indexBuffer(), baseIndex);
2472 
2473     this->setupGeometry(mesh.indexBuffer(), mesh.vertexBuffer(), baseVertex, nullptr, 0,
2474                         mesh.primitiveRestart());
2475 
2476     if (this->glCaps().drawRangeElementsSupport()) {
2477         GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount,
2478                                   GR_GL_UNSIGNED_SHORT, elementPtr));
2479     } else {
2480         GL_CALL(DrawElements(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, elementPtr));
2481     }
2482     fStats.incNumDraws();
2483 }
2484 
sendInstancedMeshToGpu(GrPrimitiveType primitiveType,const GrMesh & mesh,int vertexCount,int baseVertex,int instanceCount,int baseInstance)2485 void GrGLGpu::sendInstancedMeshToGpu(GrPrimitiveType primitiveType, const GrMesh& mesh,
2486                                      int vertexCount, int baseVertex, int instanceCount,
2487                                      int baseInstance) {
2488     GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2489     int maxInstances = this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
2490     for (int i = 0; i < instanceCount; i += maxInstances) {
2491         this->setupGeometry(nullptr, mesh.vertexBuffer(), 0, mesh.instanceBuffer(),
2492                             baseInstance + i, GrPrimitiveRestart::kNo);
2493         GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount,
2494                                     std::min(instanceCount - i, maxInstances)));
2495         fStats.incNumDraws();
2496     }
2497 }
2498 
sendIndexedInstancedMeshToGpu(GrPrimitiveType primitiveType,const GrMesh & mesh,int indexCount,int baseIndex,int baseVertex,int instanceCount,int baseInstance)2499 void GrGLGpu::sendIndexedInstancedMeshToGpu(GrPrimitiveType primitiveType, const GrMesh& mesh,
2500                                             int indexCount, int baseIndex, int baseVertex,
2501                                             int instanceCount, int baseInstance) {
2502     const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2503     const GrGLvoid* elementPtr = element_ptr(mesh.indexBuffer(), baseIndex);
2504     int maxInstances = this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
2505     for (int i = 0; i < instanceCount; i += maxInstances) {
2506         this->setupGeometry(mesh.indexBuffer(), mesh.vertexBuffer(), baseVertex,
2507                             mesh.instanceBuffer(), baseInstance + i, mesh.primitiveRestart());
2508         GL_CALL(DrawElementsInstanced(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, elementPtr,
2509                                       std::min(instanceCount - i, maxInstances)));
2510         fStats.incNumDraws();
2511     }
2512 }
2513 
onResolveRenderTarget(GrRenderTarget * target,const SkIRect & resolveRect,ForExternalIO)2514 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect,
2515                                     ForExternalIO) {
2516     // Some extensions automatically resolves the texture when it is read.
2517     SkASSERT(this->glCaps().usesMSAARenderBuffers());
2518 
2519     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
2520     SkASSERT(rt->textureFBOID() != rt->renderFBOID());
2521     SkASSERT(rt->textureFBOID() != 0 && rt->renderFBOID() != 0);
2522     this->bindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID());
2523     this->bindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID());
2524 
2525     // make sure we go through flushRenderTarget() since we've modified
2526     // the bound DRAW FBO ID.
2527     fHWBoundRenderTargetUniqueID.makeInvalid();
2528     if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
2529         // Apple's extension uses the scissor as the blit bounds.
2530         GrScissorState scissorState;
2531         scissorState.set(resolveRect);
2532         // Passing in kTopLeft_GrSurfaceOrigin will make sure no transformation of the rect
2533         // happens inside flushScissor since resolveRect is already in native device coordinates.
2534         this->flushScissor(scissorState, rt->width(), rt->height(), kTopLeft_GrSurfaceOrigin);
2535         this->disableWindowRectangles();
2536         GL_CALL(ResolveMultisampleFramebuffer());
2537     } else {
2538         int l, b, r, t;
2539         if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag &
2540             this->glCaps().blitFramebufferSupportFlags()) {
2541             l = 0;
2542             b = 0;
2543             r = target->width();
2544             t = target->height();
2545         } else {
2546             l = resolveRect.x();
2547             b = resolveRect.y();
2548             r = resolveRect.x() + resolveRect.width();
2549             t = resolveRect.y() + resolveRect.height();
2550         }
2551 
2552         // BlitFrameBuffer respects the scissor, so disable it.
2553         this->disableScissor();
2554         this->disableWindowRectangles();
2555         GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
2556     }
2557 }
2558 
2559 namespace {
2560 
2561 
gr_to_gl_stencil_op(GrStencilOp op)2562 GrGLenum gr_to_gl_stencil_op(GrStencilOp op) {
2563     static const GrGLenum gTable[kGrStencilOpCount] = {
2564         GR_GL_KEEP,        // kKeep
2565         GR_GL_ZERO,        // kZero
2566         GR_GL_REPLACE,     // kReplace
2567         GR_GL_INVERT,      // kInvert
2568         GR_GL_INCR_WRAP,   // kIncWrap
2569         GR_GL_DECR_WRAP,   // kDecWrap
2570         GR_GL_INCR,        // kIncClamp
2571         GR_GL_DECR,        // kDecClamp
2572     };
2573     static_assert(0 == (int)GrStencilOp::kKeep);
2574     static_assert(1 == (int)GrStencilOp::kZero);
2575     static_assert(2 == (int)GrStencilOp::kReplace);
2576     static_assert(3 == (int)GrStencilOp::kInvert);
2577     static_assert(4 == (int)GrStencilOp::kIncWrap);
2578     static_assert(5 == (int)GrStencilOp::kDecWrap);
2579     static_assert(6 == (int)GrStencilOp::kIncClamp);
2580     static_assert(7 == (int)GrStencilOp::kDecClamp);
2581     SkASSERT(op < (GrStencilOp)kGrStencilOpCount);
2582     return gTable[(int)op];
2583 }
2584 
set_gl_stencil(const GrGLInterface * gl,const GrStencilSettings::Face & face,GrGLenum glFace)2585 void set_gl_stencil(const GrGLInterface* gl,
2586                     const GrStencilSettings::Face& face,
2587                     GrGLenum glFace) {
2588     GrGLenum glFunc = GrToGLStencilFunc(face.fTest);
2589     GrGLenum glFailOp = gr_to_gl_stencil_op(face.fFailOp);
2590     GrGLenum glPassOp = gr_to_gl_stencil_op(face.fPassOp);
2591 
2592     GrGLint ref = face.fRef;
2593     GrGLint mask = face.fTestMask;
2594     GrGLint writeMask = face.fWriteMask;
2595 
2596     if (GR_GL_FRONT_AND_BACK == glFace) {
2597         // we call the combined func just in case separate stencil is not
2598         // supported.
2599         GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask));
2600         GR_GL_CALL(gl, StencilMask(writeMask));
2601         GR_GL_CALL(gl, StencilOp(glFailOp, GR_GL_KEEP, glPassOp));
2602     } else {
2603         GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask));
2604         GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask));
2605         GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, GR_GL_KEEP, glPassOp));
2606     }
2607 }
2608 }
2609 
flushStencil(const GrStencilSettings & stencilSettings,GrSurfaceOrigin origin)2610 void GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings, GrSurfaceOrigin origin) {
2611     if (stencilSettings.isDisabled()) {
2612         this->disableStencil();
2613     } else if (fHWStencilSettings != stencilSettings ||
2614                (stencilSettings.isTwoSided() && fHWStencilOrigin != origin)) {
2615         if (kYes_TriState != fHWStencilTestEnabled) {
2616             GL_CALL(Enable(GR_GL_STENCIL_TEST));
2617 
2618             fHWStencilTestEnabled = kYes_TriState;
2619         }
2620         if (!stencilSettings.isTwoSided()) {
2621             set_gl_stencil(this->glInterface(), stencilSettings.singleSidedFace(),
2622                            GR_GL_FRONT_AND_BACK);
2623         } else {
2624             set_gl_stencil(this->glInterface(), stencilSettings.postOriginCWFace(origin),
2625                            GR_GL_FRONT);
2626             set_gl_stencil(this->glInterface(), stencilSettings.postOriginCCWFace(origin),
2627                            GR_GL_BACK);
2628         }
2629         fHWStencilSettings = stencilSettings;
2630         fHWStencilOrigin = origin;
2631     }
2632 }
2633 
disableStencil()2634 void GrGLGpu::disableStencil() {
2635     if (kNo_TriState != fHWStencilTestEnabled) {
2636         GL_CALL(Disable(GR_GL_STENCIL_TEST));
2637 
2638         fHWStencilTestEnabled = kNo_TriState;
2639         fHWStencilSettings.invalidate();
2640     }
2641 }
2642 
flushHWAAState(GrRenderTarget * rt,bool useHWAA)2643 void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA) {
2644     // rt is only optional if useHWAA is false.
2645     SkASSERT(rt || !useHWAA);
2646 #ifdef SK_DEBUG
2647     if (useHWAA && rt->numSamples() <= 1) {
2648         SkASSERT(this->caps()->mixedSamplesSupport());
2649         SkASSERT(0 != static_cast<GrGLRenderTarget*>(rt)->renderFBOID());
2650         SkASSERT(rt->renderTargetPriv().getStencilAttachment());
2651     }
2652 #endif
2653 
2654     if (this->caps()->multisampleDisableSupport()) {
2655         if (useHWAA) {
2656             if (kYes_TriState != fMSAAEnabled) {
2657                 GL_CALL(Enable(GR_GL_MULTISAMPLE));
2658                 fMSAAEnabled = kYes_TriState;
2659             }
2660         } else {
2661             if (kNo_TriState != fMSAAEnabled) {
2662                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
2663                 fMSAAEnabled = kNo_TriState;
2664             }
2665         }
2666     }
2667 }
2668 
flushConservativeRasterState(bool enabled)2669 void GrGLGpu::flushConservativeRasterState(bool enabled) {
2670     if (this->caps()->conservativeRasterSupport()) {
2671         if (enabled) {
2672             if (kYes_TriState != fHWConservativeRasterEnabled) {
2673                 GL_CALL(Enable(GR_GL_CONSERVATIVE_RASTERIZATION));
2674                 fHWConservativeRasterEnabled = kYes_TriState;
2675             }
2676         } else {
2677             if (kNo_TriState != fHWConservativeRasterEnabled) {
2678                 GL_CALL(Disable(GR_GL_CONSERVATIVE_RASTERIZATION));
2679                 fHWConservativeRasterEnabled = kNo_TriState;
2680             }
2681         }
2682     }
2683 }
2684 
flushWireframeState(bool enabled)2685 void GrGLGpu::flushWireframeState(bool enabled) {
2686     if (this->caps()->wireframeSupport()) {
2687         if (this->caps()->wireframeMode() || enabled) {
2688             if (kYes_TriState != fHWWireframeEnabled) {
2689                 GL_CALL(PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_LINE));
2690                 fHWWireframeEnabled = kYes_TriState;
2691             }
2692         } else {
2693             if (kNo_TriState != fHWWireframeEnabled) {
2694                 GL_CALL(PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_FILL));
2695                 fHWWireframeEnabled = kNo_TriState;
2696             }
2697         }
2698     }
2699 }
2700 
flushBlendAndColorWrite(const GrXferProcessor::BlendInfo & blendInfo,const GrSwizzle & swizzle)2701 void GrGLGpu::flushBlendAndColorWrite(
2702         const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) {
2703     if (this->glCaps().neverDisableColorWrites() && !blendInfo.fWriteColor) {
2704         // We need to work around a driver bug by using a blend state that preserves the dst color,
2705         // rather than disabling color writes.
2706         GrXferProcessor::BlendInfo preserveDstBlend;
2707         preserveDstBlend.fSrcBlend = kZero_GrBlendCoeff;
2708         preserveDstBlend.fDstBlend = kOne_GrBlendCoeff;
2709         this->flushBlendAndColorWrite(preserveDstBlend, swizzle);
2710         return;
2711     }
2712 
2713     GrBlendEquation equation = blendInfo.fEquation;
2714     GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
2715     GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
2716 
2717     // Any optimization to disable blending should have already been applied and
2718     // tweaked the equation to "add" or "subtract", and the coeffs to (1, 0).
2719     bool blendOff =
2720         ((kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) &&
2721         kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff) ||
2722         !blendInfo.fWriteColor;
2723 
2724     if (blendOff) {
2725         if (kNo_TriState != fHWBlendState.fEnabled) {
2726             GL_CALL(Disable(GR_GL_BLEND));
2727 
2728             // Workaround for the ARM KHR_blend_equation_advanced blacklist issue
2729             // https://code.google.com/p/skia/issues/detail?id=3943
2730             if (kARM_GrGLVendor == this->ctxInfo().vendor() &&
2731                 GrBlendEquationIsAdvanced(fHWBlendState.fEquation)) {
2732                 SkASSERT(this->caps()->advancedBlendEquationSupport());
2733                 // Set to any basic blending equation.
2734                 GrBlendEquation blend_equation = kAdd_GrBlendEquation;
2735                 GL_CALL(BlendEquation(gXfermodeEquation2Blend[blend_equation]));
2736                 fHWBlendState.fEquation = blend_equation;
2737             }
2738 
2739             fHWBlendState.fEnabled = kNo_TriState;
2740         }
2741     } else {
2742         if (kYes_TriState != fHWBlendState.fEnabled) {
2743             GL_CALL(Enable(GR_GL_BLEND));
2744 
2745             fHWBlendState.fEnabled = kYes_TriState;
2746         }
2747 
2748         if (fHWBlendState.fEquation != equation) {
2749             GL_CALL(BlendEquation(gXfermodeEquation2Blend[equation]));
2750             fHWBlendState.fEquation = equation;
2751         }
2752 
2753         if (GrBlendEquationIsAdvanced(equation)) {
2754             SkASSERT(this->caps()->advancedBlendEquationSupport());
2755             // Advanced equations have no other blend state.
2756             return;
2757         }
2758 
2759         if (fHWBlendState.fSrcCoeff != srcCoeff || fHWBlendState.fDstCoeff != dstCoeff) {
2760             GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
2761                               gXfermodeCoeff2Blend[dstCoeff]));
2762             fHWBlendState.fSrcCoeff = srcCoeff;
2763             fHWBlendState.fDstCoeff = dstCoeff;
2764         }
2765 
2766         if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff))) {
2767             SkPMColor4f blendConst = swizzle.applyTo(blendInfo.fBlendConstant);
2768             if (!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst) {
2769                 GL_CALL(BlendColor(blendConst.fR, blendConst.fG, blendConst.fB, blendConst.fA));
2770                 fHWBlendState.fConstColor = blendConst;
2771                 fHWBlendState.fConstColorValid = true;
2772             }
2773         }
2774     }
2775 
2776     this->flushColorWrite(blendInfo.fWriteColor);
2777 }
2778 
get_gl_swizzle_values(const GrSwizzle & swizzle,GrGLenum glValues[4])2779 static void get_gl_swizzle_values(const GrSwizzle& swizzle, GrGLenum glValues[4]) {
2780     for (int i = 0; i < 4; ++i) {
2781         switch (swizzle[i]) {
2782             case 'r': glValues[i] = GR_GL_RED;   break;
2783             case 'g': glValues[i] = GR_GL_GREEN; break;
2784             case 'b': glValues[i] = GR_GL_BLUE;  break;
2785             case 'a': glValues[i] = GR_GL_ALPHA; break;
2786             case '0': glValues[i] = GR_GL_ZERO;  break;
2787             case '1': glValues[i] = GR_GL_ONE;   break;
2788             default:  SK_ABORT("Unsupported component");
2789         }
2790     }
2791 }
2792 
bindTexture(int unitIdx,GrSamplerState samplerState,const GrSwizzle & swizzle,GrGLTexture * texture)2793 void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, const GrSwizzle& swizzle,
2794                           GrGLTexture* texture) {
2795     SkASSERT(texture);
2796 
2797 #ifdef SK_DEBUG
2798     if (!this->caps()->npotTextureTileSupport()) {
2799         if (samplerState.isRepeated()) {
2800             const int w = texture->width();
2801             const int h = texture->height();
2802             SkASSERT(SkIsPow2(w) && SkIsPow2(h));
2803         }
2804     }
2805 #endif
2806 
2807     GrGpuResource::UniqueID textureID = texture->uniqueID();
2808     GrGLenum target = texture->target();
2809     if (fHWTextureUnitBindings[unitIdx].boundID(target) != textureID) {
2810         this->setTextureUnit(unitIdx);
2811         GL_CALL(BindTexture(target, texture->textureID()));
2812         fHWTextureUnitBindings[unitIdx].setBoundID(target, textureID);
2813     }
2814 
2815     if (samplerState.filter() == GrSamplerState::Filter::kMipMap) {
2816         if (!this->caps()->mipMapSupport() ||
2817             texture->texturePriv().mipMapped() == GrMipMapped::kNo) {
2818             samplerState.setFilterMode(GrSamplerState::Filter::kBilerp);
2819         }
2820     }
2821 
2822 #ifdef SK_DEBUG
2823     // We were supposed to ensure MipMaps were up-to-date before getting here.
2824     if (samplerState.filter() == GrSamplerState::Filter::kMipMap) {
2825         SkASSERT(!texture->texturePriv().mipMapsAreDirty());
2826     }
2827 #endif
2828 
2829     auto timestamp = texture->parameters()->resetTimestamp();
2830     bool setAll = timestamp < fResetTimestampForTextureParameters;
2831 
2832     const GrGLTextureParameters::SamplerOverriddenState* samplerStateToRecord = nullptr;
2833     GrGLTextureParameters::SamplerOverriddenState newSamplerState;
2834     if (fSamplerObjectCache) {
2835         fSamplerObjectCache->bindSampler(unitIdx, samplerState);
2836     } else {
2837         const GrGLTextureParameters::SamplerOverriddenState& oldSamplerState =
2838                 texture->parameters()->samplerOverriddenState();
2839         samplerStateToRecord = &newSamplerState;
2840 
2841         newSamplerState.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
2842         newSamplerState.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
2843 
2844         newSamplerState.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX(), this->glCaps());
2845         newSamplerState.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY(), this->glCaps());
2846 
2847         // These are the OpenGL default values.
2848         newSamplerState.fMinLOD = -1000.f;
2849         newSamplerState.fMaxLOD = 1000.f;
2850 
2851         if (setAll || newSamplerState.fMagFilter != oldSamplerState.fMagFilter) {
2852             this->setTextureUnit(unitIdx);
2853             GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newSamplerState.fMagFilter));
2854         }
2855         if (setAll || newSamplerState.fMinFilter != oldSamplerState.fMinFilter) {
2856             this->setTextureUnit(unitIdx);
2857             GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newSamplerState.fMinFilter));
2858         }
2859         if (this->glCaps().mipMapLevelAndLodControlSupport()) {
2860             if (setAll || newSamplerState.fMinLOD != oldSamplerState.fMinLOD) {
2861                 this->setTextureUnit(unitIdx);
2862                 GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MIN_LOD, newSamplerState.fMinLOD));
2863             }
2864             if (setAll || newSamplerState.fMaxLOD != oldSamplerState.fMaxLOD) {
2865                 this->setTextureUnit(unitIdx);
2866                 GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MAX_LOD, newSamplerState.fMaxLOD));
2867             }
2868         }
2869         if (setAll || newSamplerState.fWrapS != oldSamplerState.fWrapS) {
2870             this->setTextureUnit(unitIdx);
2871             GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newSamplerState.fWrapS));
2872         }
2873         if (setAll || newSamplerState.fWrapT != oldSamplerState.fWrapT) {
2874             this->setTextureUnit(unitIdx);
2875             GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerState.fWrapT));
2876         }
2877         if (this->glCaps().clampToBorderSupport()) {
2878             // Make sure the border color is transparent black (the default)
2879             if (setAll || oldSamplerState.fBorderColorInvalid) {
2880                 this->setTextureUnit(unitIdx);
2881                 static const GrGLfloat kTransparentBlack[4] = {0.f, 0.f, 0.f, 0.f};
2882                 GL_CALL(TexParameterfv(target, GR_GL_TEXTURE_BORDER_COLOR, kTransparentBlack));
2883             }
2884         }
2885     }
2886     GrGLTextureParameters::NonsamplerState newNonsamplerState;
2887     newNonsamplerState.fBaseMipMapLevel = 0;
2888     newNonsamplerState.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel();
2889 
2890     const GrGLTextureParameters::NonsamplerState& oldNonsamplerState =
2891             texture->parameters()->nonsamplerState();
2892     if (!this->caps()->shaderCaps()->textureSwizzleAppliedInShader()) {
2893         newNonsamplerState.fSwizzleKey = swizzle.asKey();
2894         if (setAll || swizzle.asKey() != oldNonsamplerState.fSwizzleKey) {
2895             GrGLenum glValues[4];
2896             get_gl_swizzle_values(swizzle, glValues);
2897             this->setTextureUnit(unitIdx);
2898             if (GR_IS_GR_GL(this->glStandard())) {
2899                 static_assert(sizeof(glValues[0]) == sizeof(GrGLint));
2900                 GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA,
2901                                        reinterpret_cast<const GrGLint*>(glValues)));
2902             } else if (GR_IS_GR_GL_ES(this->glStandard())) {
2903                 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
2904                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, glValues[0]));
2905                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, glValues[1]));
2906                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, glValues[2]));
2907                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, glValues[3]));
2908             }
2909         }
2910     }
2911     // These are not supported in ES2 contexts
2912     if (this->glCaps().mipMapLevelAndLodControlSupport() &&
2913         (texture->texturePriv().textureType() != GrTextureType::kExternal ||
2914          !this->glCaps().dontSetBaseOrMaxLevelForExternalTextures())) {
2915         if (newNonsamplerState.fBaseMipMapLevel != oldNonsamplerState.fBaseMipMapLevel) {
2916             this->setTextureUnit(unitIdx);
2917             GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL,
2918                                   newNonsamplerState.fBaseMipMapLevel));
2919         }
2920         if (newNonsamplerState.fMaxMipMapLevel != oldNonsamplerState.fMaxMipMapLevel) {
2921             this->setTextureUnit(unitIdx);
2922             GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL,
2923                                   newNonsamplerState.fMaxMipMapLevel));
2924         }
2925     }
2926     texture->parameters()->set(samplerStateToRecord, newNonsamplerState,
2927                                fResetTimestampForTextureParameters);
2928 }
2929 
onResetTextureBindings()2930 void GrGLGpu::onResetTextureBindings() {
2931     static constexpr GrGLenum kTargets[] = {GR_GL_TEXTURE_2D, GR_GL_TEXTURE_RECTANGLE,
2932                                             GR_GL_TEXTURE_EXTERNAL};
2933     for (int i = 0; i < this->numTextureUnits(); ++i) {
2934         this->setTextureUnit(i);
2935         for (auto target : kTargets) {
2936             if (fHWTextureUnitBindings[i].hasBeenModified(target)) {
2937                 GL_CALL(BindTexture(target, 0));
2938             }
2939         }
2940         fHWTextureUnitBindings[i].invalidateAllTargets(true);
2941     }
2942 }
2943 
flushPatchVertexCount(uint8_t count)2944 void GrGLGpu::flushPatchVertexCount(uint8_t count) {
2945     SkASSERT(this->caps()->shaderCaps()->tessellationSupport());
2946     if (fHWPatchVertexCount != count) {
2947         GL_CALL(PatchParameteri(GR_GL_PATCH_VERTICES, count));
2948         fHWPatchVertexCount = count;
2949     }
2950 }
2951 
flushColorWrite(bool writeColor)2952 void GrGLGpu::flushColorWrite(bool writeColor) {
2953     if (!writeColor) {
2954         if (kNo_TriState != fHWWriteToColor) {
2955             GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
2956                               GR_GL_FALSE, GR_GL_FALSE));
2957             fHWWriteToColor = kNo_TriState;
2958         }
2959     } else {
2960         if (kYes_TriState != fHWWriteToColor) {
2961             GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
2962             fHWWriteToColor = kYes_TriState;
2963         }
2964     }
2965 }
2966 
flushClearColor(const SkPMColor4f & color)2967 void GrGLGpu::flushClearColor(const SkPMColor4f& color) {
2968     GrGLfloat r = color.fR, g = color.fG, b = color.fB, a = color.fA;
2969     if (this->glCaps().clearToBoundaryValuesIsBroken() &&
2970         (1 == r || 0 == r) && (1 == g || 0 == g) && (1 == b || 0 == b) && (1 == a || 0 == a)) {
2971         static const GrGLfloat safeAlpha1 = nextafter(1.f, 2.f);
2972         static const GrGLfloat safeAlpha0 = nextafter(0.f, -1.f);
2973         a = (1 == a) ? safeAlpha1 : safeAlpha0;
2974     }
2975     if (r != fHWClearColor[0] || g != fHWClearColor[1] ||
2976         b != fHWClearColor[2] || a != fHWClearColor[3]) {
2977         GL_CALL(ClearColor(r, g, b, a));
2978         fHWClearColor[0] = r;
2979         fHWClearColor[1] = g;
2980         fHWClearColor[2] = b;
2981         fHWClearColor[3] = a;
2982     }
2983 }
2984 
setTextureUnit(int unit)2985 void GrGLGpu::setTextureUnit(int unit) {
2986     SkASSERT(unit >= 0 && unit < this->numTextureUnits());
2987     if (unit != fHWActiveTextureUnitIdx) {
2988         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
2989         fHWActiveTextureUnitIdx = unit;
2990     }
2991 }
2992 
bindTextureToScratchUnit(GrGLenum target,GrGLint textureID)2993 void GrGLGpu::bindTextureToScratchUnit(GrGLenum target, GrGLint textureID) {
2994     // Bind the last texture unit since it is the least likely to be used by GrGLProgram.
2995     int lastUnitIdx = this->numTextureUnits() - 1;
2996     if (lastUnitIdx != fHWActiveTextureUnitIdx) {
2997         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx));
2998         fHWActiveTextureUnitIdx = lastUnitIdx;
2999     }
3000     // Clear out the this field so that if a GrGLProgram does use this unit it will rebind the
3001     // correct texture.
3002     fHWTextureUnitBindings[lastUnitIdx].invalidateForScratchUse(target);
3003     GL_CALL(BindTexture(target, textureID));
3004 }
3005 
3006 // Determines whether glBlitFramebuffer could be used between src and dst by onCopySurface.
can_blit_framebuffer_for_copy_surface(const GrSurface * dst,const GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint,const GrGLCaps & caps)3007 static inline bool can_blit_framebuffer_for_copy_surface(const GrSurface* dst,
3008                                                          const GrSurface* src,
3009                                                          const SkIRect& srcRect,
3010                                                          const SkIPoint& dstPoint,
3011                                                          const GrGLCaps& caps) {
3012     int dstSampleCnt = 0;
3013     int srcSampleCnt = 0;
3014     if (const GrRenderTarget* rt = dst->asRenderTarget()) {
3015         dstSampleCnt = rt->numSamples();
3016     }
3017     if (const GrRenderTarget* rt = src->asRenderTarget()) {
3018         srcSampleCnt = rt->numSamples();
3019     }
3020     SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTarget()));
3021     SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTarget()));
3022 
3023     GrGLFormat dstFormat = dst->backendFormat().asGLFormat();
3024     GrGLFormat srcFormat = src->backendFormat().asGLFormat();
3025 
3026     const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
3027     const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture());
3028 
3029     GrTextureType dstTexType;
3030     GrTextureType* dstTexTypePtr = nullptr;
3031     GrTextureType srcTexType;
3032     GrTextureType* srcTexTypePtr = nullptr;
3033     if (dstTex) {
3034         dstTexType = dstTex->texturePriv().textureType();
3035         dstTexTypePtr = &dstTexType;
3036     }
3037     if (srcTex) {
3038         srcTexType = srcTex->texturePriv().textureType();
3039         srcTexTypePtr = &srcTexType;
3040     }
3041 
3042     return caps.canCopyAsBlit(dstFormat, dstSampleCnt, dstTexTypePtr,
3043                               srcFormat, srcSampleCnt, srcTexTypePtr,
3044                               src->getBoundsRect(), true, srcRect, dstPoint);
3045 }
3046 
rt_has_msaa_render_buffer(const GrGLRenderTarget * rt,const GrGLCaps & glCaps)3047 static bool rt_has_msaa_render_buffer(const GrGLRenderTarget* rt, const GrGLCaps& glCaps) {
3048     // A RT has a separate MSAA renderbuffer if:
3049     // 1) It's multisampled
3050     // 2) We're using an extension with separate MSAA renderbuffers
3051     // 3) It's not FBO 0, which is special and always auto-resolves
3052     return rt->numSamples() > 1 && glCaps.usesMSAARenderBuffers() && rt->renderFBOID() != 0;
3053 }
3054 
can_copy_texsubimage(const GrSurface * dst,const GrSurface * src,const GrGLCaps & caps)3055 static inline bool can_copy_texsubimage(const GrSurface* dst, const GrSurface* src,
3056                                         const GrGLCaps& caps) {
3057 
3058     const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget());
3059     const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
3060     const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
3061     const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture());
3062 
3063     bool dstHasMSAARenderBuffer = dstRT ? rt_has_msaa_render_buffer(dstRT, caps) : false;
3064     bool srcHasMSAARenderBuffer = srcRT ? rt_has_msaa_render_buffer(srcRT, caps) : false;
3065 
3066     GrGLFormat dstFormat = dst->backendFormat().asGLFormat();
3067     GrGLFormat srcFormat = src->backendFormat().asGLFormat();
3068 
3069     GrTextureType dstTexType;
3070     GrTextureType* dstTexTypePtr = nullptr;
3071     GrTextureType srcTexType;
3072     GrTextureType* srcTexTypePtr = nullptr;
3073     if (dstTex) {
3074         dstTexType = dstTex->texturePriv().textureType();
3075         dstTexTypePtr = &dstTexType;
3076     }
3077     if (srcTex) {
3078         srcTexType = srcTex->texturePriv().textureType();
3079         srcTexTypePtr = &srcTexType;
3080     }
3081 
3082     return caps.canCopyTexSubImage(dstFormat, dstHasMSAARenderBuffer, dstTexTypePtr,
3083                                    srcFormat, srcHasMSAARenderBuffer, srcTexTypePtr);
3084 }
3085 
3086 // If a temporary FBO was created, its non-zero ID is returned.
bindSurfaceFBOForPixelOps(GrSurface * surface,int mipLevel,GrGLenum fboTarget,TempFBOTarget tempFBOTarget)3087 void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget,
3088                                         TempFBOTarget tempFBOTarget) {
3089     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
3090     if (!rt || mipLevel > 0) {
3091         SkASSERT(surface->asTexture());
3092         GrGLTexture* texture = static_cast<GrGLTexture*>(surface->asTexture());
3093         GrGLuint texID = texture->textureID();
3094         GrGLenum target = texture->target();
3095         GrGLuint* tempFBOID;
3096         tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTempDstFBOID;
3097 
3098         if (0 == *tempFBOID) {
3099             GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID));
3100         }
3101 
3102         this->bindFramebuffer(fboTarget, *tempFBOID);
3103         GR_GL_CALL(
3104                 this->glInterface(),
3105                 FramebufferTexture2D(fboTarget, GR_GL_COLOR_ATTACHMENT0, target, texID, mipLevel));
3106         if (mipLevel == 0) {
3107             texture->baseLevelWasBoundToFBO();
3108         }
3109     } else {
3110         this->bindFramebuffer(fboTarget, rt->renderFBOID());
3111     }
3112 }
3113 
unbindSurfaceFBOForPixelOps(GrSurface * surface,int mipLevel,GrGLenum fboTarget)3114 void GrGLGpu::unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget) {
3115     // bindSurfaceFBOForPixelOps temporarily binds textures that are not render targets to
3116     if (mipLevel > 0 || !surface->asRenderTarget()) {
3117         SkASSERT(surface->asTexture());
3118         GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())->target();
3119         GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
3120                                                              GR_GL_COLOR_ATTACHMENT0,
3121                                                              textureTarget,
3122                                                              0,
3123                                                              0));
3124     }
3125 }
3126 
onFBOChanged()3127 void GrGLGpu::onFBOChanged() {
3128     if (this->caps()->workarounds().flush_on_framebuffer_change ||
3129         this->caps()->workarounds().restore_scissor_on_fbo_change) {
3130         GL_CALL(Flush());
3131     }
3132 #ifdef SK_DEBUG
3133     if (fIsExecutingCommandBuffer_DebugOnly) {
3134         SkDebugf("WARNING: GL FBO binding changed while executing a command buffer. "
3135                  "This will severely hurt performance.\n");
3136     }
3137 #endif
3138 }
3139 
bindFramebuffer(GrGLenum target,GrGLuint fboid)3140 void GrGLGpu::bindFramebuffer(GrGLenum target, GrGLuint fboid) {
3141     fStats.incRenderTargetBinds();
3142     GL_CALL(BindFramebuffer(target, fboid));
3143     if (target == GR_GL_FRAMEBUFFER || target == GR_GL_DRAW_FRAMEBUFFER) {
3144         fBoundDrawFramebuffer = fboid;
3145     }
3146 
3147     if (this->caps()->workarounds().restore_scissor_on_fbo_change) {
3148         // The driver forgets the correct scissor when modifying the FBO binding.
3149         if (!fHWScissorSettings.fRect.isInvalid()) {
3150             const GrNativeRect& r = fHWScissorSettings.fRect;
3151             GL_CALL(Scissor(r.fX, r.fY, r.fWidth, r.fHeight));
3152         }
3153     }
3154 
3155     this->onFBOChanged();
3156 }
3157 
deleteFramebuffer(GrGLuint fboid)3158 void GrGLGpu::deleteFramebuffer(GrGLuint fboid) {
3159     if (fboid == fBoundDrawFramebuffer &&
3160         this->caps()->workarounds().unbind_attachments_on_bound_render_fbo_delete) {
3161         // This workaround only applies to deleting currently bound framebuffers
3162         // on Adreno 420.  Because this is a somewhat rare case, instead of
3163         // tracking all the attachments of every framebuffer instead just always
3164         // unbind all attachments.
3165         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
3166                                         GR_GL_RENDERBUFFER, 0));
3167         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT,
3168                                         GR_GL_RENDERBUFFER, 0));
3169         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT,
3170                                         GR_GL_RENDERBUFFER, 0));
3171     }
3172 
3173     GL_CALL(DeleteFramebuffers(1, &fboid));
3174 
3175     // Deleting the currently bound framebuffer rebinds to 0.
3176     if (fboid == fBoundDrawFramebuffer) {
3177         this->onFBOChanged();
3178     }
3179 }
3180 
onCopySurface(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3181 bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
3182                             const SkIPoint& dstPoint) {
3183     // Don't prefer copying as a draw if the dst doesn't already have a FBO object.
3184     // This implicitly handles this->glCaps().useDrawInsteadOfAllRenderTargetWrites().
3185     bool preferCopy = SkToBool(dst->asRenderTarget());
3186     auto dstFormat = dst->backendFormat().asGLFormat();
3187     if (preferCopy && this->glCaps().canCopyAsDraw(dstFormat, SkToBool(src->asTexture()))) {
3188         if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
3189             return true;
3190         }
3191     }
3192 
3193     if (can_copy_texsubimage(dst, src, this->glCaps())) {
3194         this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
3195         return true;
3196     }
3197 
3198     if (can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this->glCaps())) {
3199         return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
3200     }
3201 
3202     if (!preferCopy && this->glCaps().canCopyAsDraw(dstFormat, SkToBool(src->asTexture()))) {
3203         if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
3204             return true;
3205         }
3206     }
3207 
3208     return false;
3209 }
3210 
createCopyProgram(GrTexture * srcTex)3211 bool GrGLGpu::createCopyProgram(GrTexture* srcTex) {
3212     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
3213 
3214     int progIdx = TextureToCopyProgramIdx(srcTex);
3215     const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
3216     GrSLType samplerType =
3217             GrSLCombinedSamplerTypeForTextureType(srcTex->texturePriv().textureType());
3218 
3219     if (!fCopyProgramArrayBuffer) {
3220         static const GrGLfloat vdata[] = {
3221             0, 0,
3222             0, 1,
3223             1, 0,
3224             1, 1
3225         };
3226         fCopyProgramArrayBuffer = GrGLBuffer::Make(this, sizeof(vdata), GrGpuBufferType::kVertex,
3227                                                    kStatic_GrAccessPattern, vdata);
3228     }
3229     if (!fCopyProgramArrayBuffer) {
3230         return false;
3231     }
3232 
3233     SkASSERT(!fCopyPrograms[progIdx].fProgram);
3234     GL_CALL_RET(fCopyPrograms[progIdx].fProgram, CreateProgram());
3235     if (!fCopyPrograms[progIdx].fProgram) {
3236         return false;
3237     }
3238 
3239     GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier);
3240     GrShaderVar uTexCoordXform("u_texCoordXform", kHalf4_GrSLType,
3241                                GrShaderVar::kUniform_TypeModifier);
3242     GrShaderVar uPosXform("u_posXform", kHalf4_GrSLType, GrShaderVar::kUniform_TypeModifier);
3243     GrShaderVar uTexture("u_texture", samplerType, GrShaderVar::kUniform_TypeModifier);
3244     GrShaderVar vTexCoord("v_texCoord", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier);
3245     GrShaderVar oFragColor("o_FragColor", kHalf4_GrSLType, GrShaderVar::kOut_TypeModifier);
3246 
3247     SkString vshaderTxt;
3248     if (shaderCaps->noperspectiveInterpolationSupport()) {
3249         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3250             vshaderTxt.appendf("#extension %s : require\n", extension);
3251         }
3252         vTexCoord.addModifier("noperspective");
3253     }
3254 
3255     aVertex.appendDecl(shaderCaps, &vshaderTxt);
3256     vshaderTxt.append(";");
3257     uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
3258     vshaderTxt.append(";");
3259     uPosXform.appendDecl(shaderCaps, &vshaderTxt);
3260     vshaderTxt.append(";");
3261     vTexCoord.appendDecl(shaderCaps, &vshaderTxt);
3262     vshaderTxt.append(";");
3263 
3264     vshaderTxt.append(
3265         "// Copy Program VS\n"
3266         "void main() {"
3267         "  v_texCoord = half2(a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw);"
3268         "  sk_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
3269         "  sk_Position.zw = half2(0, 1);"
3270         "}"
3271     );
3272 
3273     SkString fshaderTxt;
3274     if (shaderCaps->noperspectiveInterpolationSupport()) {
3275         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3276             fshaderTxt.appendf("#extension %s : require\n", extension);
3277         }
3278     }
3279     vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier);
3280     vTexCoord.appendDecl(shaderCaps, &fshaderTxt);
3281     fshaderTxt.append(";");
3282     uTexture.appendDecl(shaderCaps, &fshaderTxt);
3283     fshaderTxt.append(";");
3284     fshaderTxt.appendf(
3285         "// Copy Program FS\n"
3286         "void main() {"
3287         "  sk_FragColor = sample(u_texture, v_texCoord);"
3288         "}"
3289     );
3290 
3291     auto errorHandler = this->getContext()->priv().getShaderErrorHandler();
3292     SkSL::String sksl(vshaderTxt.c_str(), vshaderTxt.size());
3293     SkSL::Program::Settings settings;
3294     settings.fCaps = shaderCaps;
3295     SkSL::String glsl;
3296     std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, SkSL::Program::kVertex_Kind,
3297                                                           sksl, settings, &glsl, errorHandler);
3298     GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
3299                                                   GR_GL_VERTEX_SHADER, glsl, &fStats, errorHandler);
3300     SkASSERT(program->fInputs.isEmpty());
3301 
3302     sksl.assign(fshaderTxt.c_str(), fshaderTxt.size());
3303     program = GrSkSLtoGLSL(*fGLContext, SkSL::Program::kFragment_Kind, sksl, settings, &glsl,
3304                            errorHandler);
3305     GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
3306                                                   GR_GL_FRAGMENT_SHADER, glsl, &fStats,
3307                                                   errorHandler);
3308     SkASSERT(program->fInputs.isEmpty());
3309 
3310     GL_CALL(LinkProgram(fCopyPrograms[progIdx].fProgram));
3311 
3312     GL_CALL_RET(fCopyPrograms[progIdx].fTextureUniform,
3313                 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texture"));
3314     GL_CALL_RET(fCopyPrograms[progIdx].fPosXformUniform,
3315                 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_posXform"));
3316     GL_CALL_RET(fCopyPrograms[progIdx].fTexCoordXformUniform,
3317                 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordXform"));
3318 
3319     GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex"));
3320 
3321     GL_CALL(DeleteShader(vshader));
3322     GL_CALL(DeleteShader(fshader));
3323 
3324     return true;
3325 }
3326 
createMipmapProgram(int progIdx)3327 bool GrGLGpu::createMipmapProgram(int progIdx) {
3328     const bool oddWidth = SkToBool(progIdx & 0x2);
3329     const bool oddHeight = SkToBool(progIdx & 0x1);
3330     const int numTaps = (oddWidth ? 2 : 1) * (oddHeight ? 2 : 1);
3331 
3332     const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
3333 
3334     SkASSERT(!fMipmapPrograms[progIdx].fProgram);
3335     GL_CALL_RET(fMipmapPrograms[progIdx].fProgram, CreateProgram());
3336     if (!fMipmapPrograms[progIdx].fProgram) {
3337         return false;
3338     }
3339 
3340     GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier);
3341     GrShaderVar uTexCoordXform("u_texCoordXform", kHalf4_GrSLType,
3342                                GrShaderVar::kUniform_TypeModifier);
3343     GrShaderVar uTexture("u_texture", kTexture2DSampler_GrSLType,
3344                          GrShaderVar::kUniform_TypeModifier);
3345     // We need 1, 2, or 4 texture coordinates (depending on parity of each dimension):
3346     GrShaderVar vTexCoords[] = {
3347         GrShaderVar("v_texCoord0", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier),
3348         GrShaderVar("v_texCoord1", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier),
3349         GrShaderVar("v_texCoord2", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier),
3350         GrShaderVar("v_texCoord3", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier),
3351     };
3352     GrShaderVar oFragColor("o_FragColor", kHalf4_GrSLType,GrShaderVar::kOut_TypeModifier);
3353 
3354     SkString vshaderTxt;
3355     if (shaderCaps->noperspectiveInterpolationSupport()) {
3356         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3357             vshaderTxt.appendf("#extension %s : require\n", extension);
3358         }
3359         vTexCoords[0].addModifier("noperspective");
3360         vTexCoords[1].addModifier("noperspective");
3361         vTexCoords[2].addModifier("noperspective");
3362         vTexCoords[3].addModifier("noperspective");
3363     }
3364 
3365     aVertex.appendDecl(shaderCaps, &vshaderTxt);
3366     vshaderTxt.append(";");
3367     uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
3368     vshaderTxt.append(";");
3369     for (int i = 0; i < numTaps; ++i) {
3370         vTexCoords[i].appendDecl(shaderCaps, &vshaderTxt);
3371         vshaderTxt.append(";");
3372     }
3373 
3374     vshaderTxt.append(
3375         "// Mipmap Program VS\n"
3376         "void main() {"
3377         "  sk_Position.xy = a_vertex * half2(2, 2) - half2(1, 1);"
3378         "  sk_Position.zw = half2(0, 1);"
3379     );
3380 
3381     // Insert texture coordinate computation:
3382     if (oddWidth && oddHeight) {
3383         vshaderTxt.append(
3384             "  v_texCoord0 = a_vertex.xy * u_texCoordXform.yw;"
3385             "  v_texCoord1 = a_vertex.xy * u_texCoordXform.yw + half2(u_texCoordXform.x, 0);"
3386             "  v_texCoord2 = a_vertex.xy * u_texCoordXform.yw + half2(0, u_texCoordXform.z);"
3387             "  v_texCoord3 = a_vertex.xy * u_texCoordXform.yw + u_texCoordXform.xz;"
3388         );
3389     } else if (oddWidth) {
3390         vshaderTxt.append(
3391             "  v_texCoord0 = a_vertex.xy * half2(u_texCoordXform.y, 1);"
3392             "  v_texCoord1 = a_vertex.xy * half2(u_texCoordXform.y, 1) + half2(u_texCoordXform.x, 0);"
3393         );
3394     } else if (oddHeight) {
3395         vshaderTxt.append(
3396             "  v_texCoord0 = a_vertex.xy * half2(1, u_texCoordXform.w);"
3397             "  v_texCoord1 = a_vertex.xy * half2(1, u_texCoordXform.w) + half2(0, u_texCoordXform.z);"
3398         );
3399     } else {
3400         vshaderTxt.append(
3401             "  v_texCoord0 = a_vertex.xy;"
3402         );
3403     }
3404 
3405     vshaderTxt.append("}");
3406 
3407     SkString fshaderTxt;
3408     if (shaderCaps->noperspectiveInterpolationSupport()) {
3409         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3410             fshaderTxt.appendf("#extension %s : require\n", extension);
3411         }
3412     }
3413     for (int i = 0; i < numTaps; ++i) {
3414         vTexCoords[i].setTypeModifier(GrShaderVar::kIn_TypeModifier);
3415         vTexCoords[i].appendDecl(shaderCaps, &fshaderTxt);
3416         fshaderTxt.append(";");
3417     }
3418     uTexture.appendDecl(shaderCaps, &fshaderTxt);
3419     fshaderTxt.append(";");
3420     fshaderTxt.append(
3421         "// Mipmap Program FS\n"
3422         "void main() {"
3423     );
3424 
3425     if (oddWidth && oddHeight) {
3426         fshaderTxt.append(
3427             "  sk_FragColor = (sample(u_texture, v_texCoord0) + "
3428             "                  sample(u_texture, v_texCoord1) + "
3429             "                  sample(u_texture, v_texCoord2) + "
3430             "                  sample(u_texture, v_texCoord3)) * 0.25;"
3431         );
3432     } else if (oddWidth || oddHeight) {
3433         fshaderTxt.append(
3434             "  sk_FragColor = (sample(u_texture, v_texCoord0) + "
3435             "                  sample(u_texture, v_texCoord1)) * 0.5;"
3436         );
3437     } else {
3438         fshaderTxt.append(
3439             "  sk_FragColor = sample(u_texture, v_texCoord0);"
3440         );
3441     }
3442 
3443     fshaderTxt.append("}");
3444 
3445     auto errorHandler = this->getContext()->priv().getShaderErrorHandler();
3446     SkSL::String sksl(vshaderTxt.c_str(), vshaderTxt.size());
3447     SkSL::Program::Settings settings;
3448     settings.fCaps = shaderCaps;
3449     SkSL::String glsl;
3450     std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, SkSL::Program::kVertex_Kind,
3451                                                           sksl, settings, &glsl, errorHandler);
3452     GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
3453                                                   GR_GL_VERTEX_SHADER, glsl, &fStats, errorHandler);
3454     SkASSERT(program->fInputs.isEmpty());
3455 
3456     sksl.assign(fshaderTxt.c_str(), fshaderTxt.size());
3457     program = GrSkSLtoGLSL(*fGLContext, SkSL::Program::kFragment_Kind, sksl, settings, &glsl,
3458                            errorHandler);
3459     GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
3460                                                   GR_GL_FRAGMENT_SHADER, glsl, &fStats,
3461                                                   errorHandler);
3462     SkASSERT(program->fInputs.isEmpty());
3463 
3464     GL_CALL(LinkProgram(fMipmapPrograms[progIdx].fProgram));
3465 
3466     GL_CALL_RET(fMipmapPrograms[progIdx].fTextureUniform,
3467                 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texture"));
3468     GL_CALL_RET(fMipmapPrograms[progIdx].fTexCoordXformUniform,
3469                 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texCoordXform"));
3470 
3471     GL_CALL(BindAttribLocation(fMipmapPrograms[progIdx].fProgram, 0, "a_vertex"));
3472 
3473     GL_CALL(DeleteShader(vshader));
3474     GL_CALL(DeleteShader(fshader));
3475 
3476     return true;
3477 }
3478 
copySurfaceAsDraw(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3479 bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
3480                                 const SkIPoint& dstPoint) {
3481     auto* srcTex = static_cast<GrGLTexture*>(src->asTexture());
3482     auto* dstTex = static_cast<GrGLTexture*>(src->asTexture());
3483     auto* dstRT  = static_cast<GrGLRenderTarget*>(src->asRenderTarget());
3484     if (!srcTex) {
3485         return false;
3486     }
3487     int progIdx = TextureToCopyProgramIdx(srcTex);
3488     if (!dstRT) {
3489         SkASSERT(dstTex);
3490         if (!this->glCaps().isFormatRenderable(dstTex->format(), 1)) {
3491             return false;
3492         }
3493     }
3494     if (!fCopyPrograms[progIdx].fProgram) {
3495         if (!this->createCopyProgram(srcTex)) {
3496             SkDebugf("Failed to create copy program.\n");
3497             return false;
3498         }
3499     }
3500     int w = srcRect.width();
3501     int h = srcRect.height();
3502     // We don't swizzle at all in our copies.
3503     this->bindTexture(0, GrSamplerState::Filter::kNearest, GrSwizzle::RGBA(), srcTex);
3504     this->bindSurfaceFBOForPixelOps(dst, 0, GR_GL_FRAMEBUFFER, kDst_TempFBOTarget);
3505     this->flushViewport(dst->width(), dst->height());
3506     fHWBoundRenderTargetUniqueID.makeInvalid();
3507     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
3508     this->flushProgram(fCopyPrograms[progIdx].fProgram);
3509     fHWVertexArrayState.setVertexArrayID(this, 0);
3510     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
3511     attribs->enableVertexArrays(this, 1);
3512     attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kFloat2_GrVertexAttribType,
3513                  kFloat2_GrSLType, 2 * sizeof(GrGLfloat), 0);
3514     // dst rect edges in NDC (-1 to 1)
3515     int dw = dst->width();
3516     int dh = dst->height();
3517     GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f;
3518     GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
3519     GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f;
3520     GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
3521     GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft;
3522     GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w);
3523     GrGLfloat sy0 = (GrGLfloat)srcRect.fTop;
3524     GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h);
3525     int sw = src->width();
3526     int sh = src->height();
3527     if (srcTex->texturePriv().textureType() != GrTextureType::kRectangle) {
3528         // src rect edges in normalized texture space (0 to 1)
3529         sx0 /= sw;
3530         sx1 /= sw;
3531         sy0 /= sh;
3532         sy1 /= sh;
3533     }
3534     GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
3535     GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,
3536                       sx1 - sx0, sy1 - sy0, sx0, sy0));
3537     GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0));
3538     this->flushBlendAndColorWrite(GrXferProcessor::BlendInfo(), GrSwizzle::RGBA());
3539     this->flushHWAAState(nullptr, false);
3540     this->flushConservativeRasterState(false);
3541     this->flushWireframeState(false);
3542     this->disableScissor();
3543     this->disableWindowRectangles();
3544     this->disableStencil();
3545     if (this->glCaps().srgbWriteControl()) {
3546         this->flushFramebufferSRGB(true);
3547     }
3548     GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
3549     this->unbindSurfaceFBOForPixelOps(dst, 0, GR_GL_FRAMEBUFFER);
3550     // The rect is already in device space so we pass in kTopLeft so no flip is done.
3551     this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
3552     return true;
3553 }
3554 
copySurfaceAsCopyTexSubImage(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3555 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
3556                                            const SkIPoint& dstPoint) {
3557     SkASSERT(can_copy_texsubimage(dst, src, this->glCaps()));
3558     this->bindSurfaceFBOForPixelOps(src, 0, GR_GL_FRAMEBUFFER, kSrc_TempFBOTarget);
3559     GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture());
3560     SkASSERT(dstTex);
3561     // We modified the bound FBO
3562     fHWBoundRenderTargetUniqueID.makeInvalid();
3563 
3564     this->bindTextureToScratchUnit(dstTex->target(), dstTex->textureID());
3565     GL_CALL(CopyTexSubImage2D(dstTex->target(), 0,
3566                               dstPoint.fX, dstPoint.fY,
3567                               srcRect.fLeft, srcRect.fTop,
3568                               srcRect.width(), srcRect.height()));
3569     this->unbindSurfaceFBOForPixelOps(src, 0, GR_GL_FRAMEBUFFER);
3570     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
3571                                         srcRect.width(), srcRect.height());
3572     // The rect is already in device space so we pass in kTopLeft so no flip is done.
3573     this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
3574 }
3575 
copySurfaceAsBlitFramebuffer(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3576 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
3577                                            const SkIPoint& dstPoint) {
3578     SkASSERT(can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this->glCaps()));
3579     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
3580                                         srcRect.width(), srcRect.height());
3581     if (dst == src) {
3582         if (SkIRect::Intersects(dstRect, srcRect)) {
3583             return false;
3584         }
3585     }
3586 
3587     this->bindSurfaceFBOForPixelOps(dst, 0, GR_GL_DRAW_FRAMEBUFFER, kDst_TempFBOTarget);
3588     this->bindSurfaceFBOForPixelOps(src, 0, GR_GL_READ_FRAMEBUFFER, kSrc_TempFBOTarget);
3589     // We modified the bound FBO
3590     fHWBoundRenderTargetUniqueID.makeInvalid();
3591 
3592     // BlitFrameBuffer respects the scissor, so disable it.
3593     this->disableScissor();
3594     this->disableWindowRectangles();
3595 
3596     GL_CALL(BlitFramebuffer(srcRect.fLeft,
3597                             srcRect.fTop,
3598                             srcRect.fRight,
3599                             srcRect.fBottom,
3600                             dstRect.fLeft,
3601                             dstRect.fTop,
3602                             dstRect.fRight,
3603                             dstRect.fBottom,
3604                             GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
3605     this->unbindSurfaceFBOForPixelOps(dst, 0, GR_GL_DRAW_FRAMEBUFFER);
3606     this->unbindSurfaceFBOForPixelOps(src, 0, GR_GL_READ_FRAMEBUFFER);
3607 
3608     // The rect is already in device space so we pass in kTopLeft so no flip is done.
3609     this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
3610     return true;
3611 }
3612 
onRegenerateMipMapLevels(GrTexture * texture)3613 bool GrGLGpu::onRegenerateMipMapLevels(GrTexture* texture) {
3614     auto glTex = static_cast<GrGLTexture*>(texture);
3615     // Mipmaps are only supported on 2D textures:
3616     if (GR_GL_TEXTURE_2D != glTex->target()) {
3617         return false;
3618     }
3619     GrGLFormat format = glTex->format();
3620     // Manual implementation of mipmap generation, to work around driver bugs w/sRGB.
3621     // Uses draw calls to do a series of downsample operations to successive mips.
3622 
3623     // The manual approach requires the ability to limit which level we're sampling and that the
3624     // destination can be bound to a FBO:
3625     if (!this->glCaps().doManualMipmapping() || !this->glCaps().isFormatRenderable(format, 1)) {
3626         GrGLenum target = glTex->target();
3627         this->bindTextureToScratchUnit(target, glTex->textureID());
3628         GL_CALL(GenerateMipmap(glTex->target()));
3629         return true;
3630     }
3631 
3632     int width = texture->width();
3633     int height = texture->height();
3634     int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1;
3635     SkASSERT(levelCount == texture->texturePriv().maxMipMapLevel() + 1);
3636 
3637     // Create (if necessary), then bind temporary FBO:
3638     if (0 == fTempDstFBOID) {
3639         GL_CALL(GenFramebuffers(1, &fTempDstFBOID));
3640     }
3641     this->bindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID);
3642     fHWBoundRenderTargetUniqueID.makeInvalid();
3643 
3644     // Bind the texture, to get things configured for filtering.
3645     // We'll be changing our base level further below:
3646     this->setTextureUnit(0);
3647     // The mipmap program does not do any swizzling.
3648     this->bindTexture(0, GrSamplerState::Filter::kBilerp, GrSwizzle::RGBA(), glTex);
3649 
3650     // Vertex data:
3651     if (!fMipmapProgramArrayBuffer) {
3652         static const GrGLfloat vdata[] = {
3653             0, 0,
3654             0, 1,
3655             1, 0,
3656             1, 1
3657         };
3658         fMipmapProgramArrayBuffer = GrGLBuffer::Make(this, sizeof(vdata), GrGpuBufferType::kVertex,
3659                                                      kStatic_GrAccessPattern, vdata);
3660     }
3661     if (!fMipmapProgramArrayBuffer) {
3662         return false;
3663     }
3664 
3665     fHWVertexArrayState.setVertexArrayID(this, 0);
3666 
3667     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
3668     attribs->enableVertexArrays(this, 1);
3669     attribs->set(this, 0, fMipmapProgramArrayBuffer.get(), kFloat2_GrVertexAttribType,
3670                  kFloat2_GrSLType, 2 * sizeof(GrGLfloat), 0);
3671 
3672     // Set "simple" state once:
3673     this->flushBlendAndColorWrite(GrXferProcessor::BlendInfo(), GrSwizzle::RGBA());
3674     this->flushHWAAState(nullptr, false);
3675     this->disableScissor();
3676     this->disableWindowRectangles();
3677     this->disableStencil();
3678 
3679     // Do all the blits:
3680     width = texture->width();
3681     height = texture->height();
3682 
3683     for (GrGLint level = 1; level < levelCount; ++level) {
3684         // Get and bind the program for this particular downsample (filter shape can vary):
3685         int progIdx = TextureSizeToMipmapProgramIdx(width, height);
3686         if (!fMipmapPrograms[progIdx].fProgram) {
3687             if (!this->createMipmapProgram(progIdx)) {
3688                 SkDebugf("Failed to create mipmap program.\n");
3689                 // Invalidate all params to cover base level change in a previous iteration.
3690                 glTex->textureParamsModified();
3691                 return false;
3692             }
3693         }
3694         this->flushProgram(fMipmapPrograms[progIdx].fProgram);
3695 
3696         // Texcoord uniform is expected to contain (1/w, (w-1)/w, 1/h, (h-1)/h)
3697         const float invWidth = 1.0f / width;
3698         const float invHeight = 1.0f / height;
3699         GL_CALL(Uniform4f(fMipmapPrograms[progIdx].fTexCoordXformUniform,
3700                           invWidth, (width - 1) * invWidth, invHeight, (height - 1) * invHeight));
3701         GL_CALL(Uniform1i(fMipmapPrograms[progIdx].fTextureUniform, 0));
3702 
3703         // Only sample from previous mip
3704         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level - 1));
3705 
3706         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_TEXTURE_2D,
3707                                      glTex->textureID(), level));
3708 
3709         width = std::max(1, width / 2);
3710         height = std::max(1, height / 2);
3711         this->flushViewport(width, height);
3712 
3713         GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
3714     }
3715 
3716     // Unbind:
3717     GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
3718                                  GR_GL_TEXTURE_2D, 0, 0));
3719 
3720     // We modified the base level param.
3721     GrGLTextureParameters::NonsamplerState nonsamplerState = glTex->parameters()->nonsamplerState();
3722     // We drew the 2nd to last level into the last level.
3723     nonsamplerState.fBaseMipMapLevel = levelCount - 2;
3724     glTex->parameters()->set(nullptr, nonsamplerState, fResetTimestampForTextureParameters);
3725 
3726     return true;
3727 }
3728 
querySampleLocations(GrRenderTarget * renderTarget,SkTArray<SkPoint> * sampleLocations)3729 void GrGLGpu::querySampleLocations(
3730         GrRenderTarget* renderTarget, SkTArray<SkPoint>* sampleLocations) {
3731     this->flushRenderTargetNoColorWrites(static_cast<GrGLRenderTarget*>(renderTarget));
3732 
3733     int effectiveSampleCnt;
3734     GR_GL_GetIntegerv(this->glInterface(), GR_GL_SAMPLES, &effectiveSampleCnt);
3735     SkASSERT(effectiveSampleCnt >= renderTarget->numSamples());
3736 
3737     sampleLocations->reset(effectiveSampleCnt);
3738     for (int i = 0; i < effectiveSampleCnt; ++i) {
3739         GL_CALL(GetMultisamplefv(GR_GL_SAMPLE_POSITION, i, &(*sampleLocations)[i].fX));
3740     }
3741 }
3742 
xferBarrier(GrRenderTarget * rt,GrXferBarrierType type)3743 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) {
3744     SkASSERT(type);
3745     switch (type) {
3746         case kTexture_GrXferBarrierType: {
3747             GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt);
3748             SkASSERT(glrt->textureFBOID() != 0 && glrt->renderFBOID() != 0);
3749             if (glrt->textureFBOID() != glrt->renderFBOID()) {
3750                 // The render target uses separate storage so no need for glTextureBarrier.
3751                 // FIXME: The render target will resolve automatically when its texture is bound,
3752                 // but we could resolve only the bounds that will be read if we do it here instead.
3753                 return;
3754             }
3755             SkASSERT(this->caps()->textureBarrierSupport());
3756             GL_CALL(TextureBarrier());
3757             return;
3758         }
3759         case kBlend_GrXferBarrierType:
3760             SkASSERT(GrCaps::kAdvanced_BlendEquationSupport ==
3761                      this->caps()->blendEquationSupport());
3762             GL_CALL(BlendBarrier());
3763             return;
3764         default: break; // placate compiler warnings that kNone not handled
3765     }
3766 }
3767 
insertManualFramebufferBarrier()3768 void GrGLGpu::insertManualFramebufferBarrier() {
3769     SkASSERT(this->caps()->requiresManualFBBarrierAfterTessellatedStencilDraw());
3770     GL_CALL(MemoryBarrier(GR_GL_FRAMEBUFFER_BARRIER_BIT));
3771 }
3772 
onCreateBackendTexture(SkISize dimensions,const GrBackendFormat & format,GrRenderable renderable,GrMipMapped mipMapped,GrProtected isProtected,const BackendTextureData * data)3773 GrBackendTexture GrGLGpu::onCreateBackendTexture(SkISize dimensions,
3774                                                  const GrBackendFormat& format,
3775                                                  GrRenderable renderable,
3776                                                  GrMipMapped mipMapped,
3777                                                  GrProtected isProtected,
3778                                                  const BackendTextureData* data) {
3779     // We don't support protected textures in GL.
3780     if (isProtected == GrProtected::kYes) {
3781         return {};
3782     }
3783 
3784     this->handleDirtyContext();
3785 
3786     GrGLFormat glFormat = format.asGLFormat();
3787     if (glFormat == GrGLFormat::kUnknown) {
3788         return {};
3789     }
3790 
3791     int numMipLevels = 1;
3792     if (mipMapped == GrMipMapped::kYes) {
3793         numMipLevels = SkMipMap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
3794     }
3795 
3796     // Compressed formats go through onCreateCompressedBackendTexture
3797     SkASSERT(!GrGLFormatIsCompressed(glFormat));
3798 
3799     GrGLTextureInfo info;
3800     GrGLTextureParameters::SamplerOverriddenState initialState;
3801 
3802     if (glFormat == GrGLFormat::kUnknown) {
3803         return {};
3804     }
3805 
3806     info.fTarget = GR_GL_TEXTURE_2D;
3807     info.fFormat = GrGLFormatToEnum(glFormat);
3808     info.fID = this->createTexture2D(dimensions, glFormat, renderable, &initialState, numMipLevels);
3809     if (!info.fID) {
3810         return {};
3811     }
3812 
3813     SkASSERT(!data || data->type() != BackendTextureData::Type::kCompressed);
3814     if (data && data->type() == BackendTextureData::Type::kPixmaps) {
3815         SkTDArray<GrMipLevel> texels;
3816         GrColorType colorType = SkColorTypeToGrColorType(data->pixmap(0).colorType());
3817         texels.append(numMipLevels);
3818         for (int i = 0; i < numMipLevels; ++i) {
3819             texels[i] = {data->pixmap(i).addr(), data->pixmap(i).rowBytes()};
3820         }
3821         if (!this->uploadTexData(glFormat, colorType, dimensions.width(), dimensions.height(),
3822                                  GR_GL_TEXTURE_2D, 0, 0, dimensions.width(), dimensions.height(),
3823                                  colorType, texels.begin(), texels.count())) {
3824             GL_CALL(DeleteTextures(1, &info.fID));
3825             return {};
3826         }
3827     } else if (data && data->type() == BackendTextureData::Type::kColor) {
3828         // TODO: Unify this with the clear texture code in onCreateTexture().
3829         GrColorType colorType;
3830         GrGLenum externalFormat, externalType;
3831         this->glCaps().getTexSubImageDefaultFormatTypeAndColorType(glFormat, &externalFormat,
3832                                                                    &externalType, &colorType);
3833         if (colorType == GrColorType::kUnknown) {
3834             GL_CALL(DeleteTextures(1, &info.fID));
3835             return {};
3836         }
3837 
3838         // Make one tight image at the base size and reuse it for smaller levels.
3839         GrImageInfo ii(colorType, kUnpremul_SkAlphaType, nullptr, dimensions);
3840         auto rb = ii.minRowBytes();
3841         std::unique_ptr<char[]> pixelStorage(new char[rb * dimensions.height()]);
3842         if (!GrClearImage(ii, pixelStorage.get(), rb, data->color())) {
3843             GL_CALL(DeleteTextures(1, &info.fID));
3844             return {};
3845         }
3846 
3847         GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1));
3848         SkISize levelDimensions = dimensions;
3849         for (int i = 0; i < numMipLevels; ++i) {
3850             GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, i, 0, 0, levelDimensions.width(),
3851                                   levelDimensions.height(), externalFormat, externalType,
3852                                   pixelStorage.get()));
3853             levelDimensions = {std::max(1, levelDimensions.width() /2),
3854                                std::max(1, levelDimensions.height()/2)};
3855         }
3856     }
3857     // Unbind this texture from the scratch texture unit.
3858     this->bindTextureToScratchUnit(GR_GL_TEXTURE_2D, 0);
3859 
3860     auto parameters = sk_make_sp<GrGLTextureParameters>();
3861     // The non-sampler params are still at their default values.
3862     parameters->set(&initialState, GrGLTextureParameters::NonsamplerState(),
3863                     fResetTimestampForTextureParameters);
3864 
3865     return GrBackendTexture(dimensions.width(), dimensions.height(), mipMapped, info,
3866                             std::move(parameters));
3867 }
3868 
deleteBackendTexture(const GrBackendTexture & tex)3869 void GrGLGpu::deleteBackendTexture(const GrBackendTexture& tex) {
3870     SkASSERT(GrBackendApi::kOpenGL == tex.backend());
3871 
3872     GrGLTextureInfo info;
3873     if (tex.getGLTextureInfo(&info)) {
3874         GL_CALL(DeleteTextures(1, &info.fID));
3875     }
3876 }
3877 
3878 #if GR_TEST_UTILS
3879 
isTestingOnlyBackendTexture(const GrBackendTexture & tex) const3880 bool GrGLGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
3881     SkASSERT(GrBackendApi::kOpenGL == tex.backend());
3882 
3883     GrGLTextureInfo info;
3884     if (!tex.getGLTextureInfo(&info)) {
3885         return false;
3886     }
3887 
3888     GrGLboolean result;
3889     GL_CALL_RET(result, IsTexture(info.fID));
3890 
3891     return (GR_GL_TRUE == result);
3892 }
3893 
createTestingOnlyBackendRenderTarget(int w,int h,GrColorType colorType)3894 GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h,
3895                                                                     GrColorType colorType) {
3896     if (w > this->caps()->maxRenderTargetSize() || h > this->caps()->maxRenderTargetSize()) {
3897         return GrBackendRenderTarget();  // invalid
3898     }
3899     this->handleDirtyContext();
3900     auto format = this->glCaps().getFormatFromColorType(colorType);
3901     if (!this->glCaps().isFormatRenderable(format, 1)) {
3902         return {};
3903     }
3904     bool useTexture = format == GrGLFormat::kBGRA8;
3905     int sFormatIdx = this->getCompatibleStencilIndex(format);
3906     if (sFormatIdx < 0) {
3907         return {};
3908     }
3909     GrGLuint colorID = 0;
3910     GrGLuint stencilID = 0;
3911     auto deleteIDs = [&] {
3912         if (colorID) {
3913             if (useTexture) {
3914                 GL_CALL(DeleteTextures(1, &colorID));
3915             } else {
3916                 GL_CALL(DeleteRenderbuffers(1, &colorID));
3917             }
3918         }
3919         if (stencilID) {
3920             GL_CALL(DeleteRenderbuffers(1, &stencilID));
3921         }
3922     };
3923 
3924     if (useTexture) {
3925         GL_CALL(GenTextures(1, &colorID));
3926     } else {
3927         GL_CALL(GenRenderbuffers(1, &colorID));
3928     }
3929     GL_CALL(GenRenderbuffers(1, &stencilID));
3930     if (!stencilID || !colorID) {
3931         deleteIDs();
3932         return {};
3933     }
3934 
3935     GrGLFramebufferInfo info;
3936     info.fFBOID = 0;
3937     info.fFormat = GrGLFormatToEnum(format);
3938     GL_CALL(GenFramebuffers(1, &info.fFBOID));
3939     if (!info.fFBOID) {
3940         deleteIDs();
3941         return {};
3942     }
3943 
3944     this->invalidateBoundRenderTarget();
3945 
3946     this->bindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID);
3947     if (useTexture) {
3948         GrGLTextureParameters::SamplerOverriddenState initialState;
3949         colorID = this->createTexture2D({w, h}, format, GrRenderable::kYes, &initialState, 1);
3950         if (!colorID) {
3951             deleteIDs();
3952             return {};
3953         }
3954         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_TEXTURE_2D,
3955                                      colorID, 0));
3956     } else {
3957         GrGLenum renderBufferFormat = this->glCaps().getRenderbufferInternalFormat(format);
3958         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, colorID));
3959         GL_ALLOC_CALL(this->glInterface(),
3960                       RenderbufferStorage(GR_GL_RENDERBUFFER, renderBufferFormat, w, h));
3961         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
3962                                         GR_GL_RENDERBUFFER, colorID));
3963     }
3964     GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, stencilID));
3965     auto stencilBufferFormat = this->glCaps().stencilFormats()[sFormatIdx].fInternalFormat;
3966     GL_ALLOC_CALL(this->glInterface(),
3967                   RenderbufferStorage(GR_GL_RENDERBUFFER, stencilBufferFormat, w, h));
3968     GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT, GR_GL_RENDERBUFFER,
3969                                     stencilID));
3970     if (this->glCaps().stencilFormats()[sFormatIdx].fPacked) {
3971         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT,
3972                                         GR_GL_RENDERBUFFER, stencilID));
3973     }
3974 
3975     // We don't want to have to recover the renderbuffer/texture IDs later to delete them. OpenGL
3976     // has this rule that if a renderbuffer/texture is deleted and a FBO other than the current FBO
3977     // has the RB attached then deletion is delayed. So we unbind the FBO here and delete the
3978     // renderbuffers/texture.
3979     this->bindFramebuffer(GR_GL_FRAMEBUFFER, 0);
3980     deleteIDs();
3981 
3982     this->bindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID);
3983     GrGLenum status;
3984     GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
3985     if (GR_GL_FRAMEBUFFER_COMPLETE != status) {
3986         this->deleteFramebuffer(info.fFBOID);
3987         return {};
3988     }
3989     auto stencilBits = SkToInt(this->glCaps().stencilFormats()[sFormatIdx].fStencilBits);
3990 
3991     GrBackendRenderTarget beRT = GrBackendRenderTarget(w, h, 1, stencilBits, info);
3992     SkASSERT(this->caps()->areColorTypeAndFormatCompatible(colorType, beRT.getBackendFormat()));
3993     return beRT;
3994 }
3995 
deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget & backendRT)3996 void GrGLGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget& backendRT) {
3997     SkASSERT(GrBackendApi::kOpenGL == backendRT.backend());
3998     GrGLFramebufferInfo info;
3999     if (backendRT.getGLFramebufferInfo(&info)) {
4000         if (info.fFBOID) {
4001             this->deleteFramebuffer(info.fFBOID);
4002         }
4003     }
4004 }
4005 
testingOnly_flushGpuAndSync()4006 void GrGLGpu::testingOnly_flushGpuAndSync() {
4007     GL_CALL(Finish());
4008 }
4009 #endif
4010 
4011 ///////////////////////////////////////////////////////////////////////////////
4012 
bindInternalVertexArray(GrGLGpu * gpu,const GrBuffer * ibuf)4013 GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu,
4014                                                                            const GrBuffer* ibuf) {
4015     GrGLAttribArrayState* attribState;
4016 
4017     if (gpu->glCaps().isCoreProfile()) {
4018         if (!fCoreProfileVertexArray) {
4019             GrGLuint arrayID;
4020             GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID));
4021             int attrCount = gpu->glCaps().maxVertexAttributes();
4022             fCoreProfileVertexArray = new GrGLVertexArray(arrayID, attrCount);
4023         }
4024         if (ibuf) {
4025             attribState = fCoreProfileVertexArray->bindWithIndexBuffer(gpu, ibuf);
4026         } else {
4027             attribState = fCoreProfileVertexArray->bind(gpu);
4028         }
4029     } else {
4030         if (ibuf) {
4031             // bindBuffer implicitly binds VAO 0 when binding an index buffer.
4032             gpu->bindBuffer(GrGpuBufferType::kIndex, ibuf);
4033         } else {
4034             this->setVertexArrayID(gpu, 0);
4035         }
4036         int attrCount = gpu->glCaps().maxVertexAttributes();
4037         if (fDefaultVertexArrayAttribState.count() != attrCount) {
4038             fDefaultVertexArrayAttribState.resize(attrCount);
4039         }
4040         attribState = &fDefaultVertexArrayAttribState;
4041     }
4042     return attribState;
4043 }
4044 
onFinishFlush(GrSurfaceProxy * [],int,SkSurface::BackendSurfaceAccess access,const GrFlushInfo & info,const GrPrepareForExternalIORequests &)4045 bool GrGLGpu::onFinishFlush(GrSurfaceProxy*[], int, SkSurface::BackendSurfaceAccess access,
4046                             const GrFlushInfo& info, const GrPrepareForExternalIORequests&) {
4047     // If we inserted semaphores during the flush, we need to call GLFlush.
4048     bool insertedSemaphore = info.fNumSemaphores > 0 && this->caps()->semaphoreSupport();
4049     // We call finish if the client told us to sync or if we have a finished proc but don't support
4050     // GLsync objects.
4051     bool finish = (info.fFlags & kSyncCpu_GrFlushFlag) ||
4052                   (info.fFinishedProc && !this->caps()->fenceSyncSupport());
4053     if (finish) {
4054         GL_CALL(Finish());
4055         // After a finish everything previously sent to GL is done.
4056         for (const auto& cb : fFinishCallbacks) {
4057             cb.fCallback(cb.fContext);
4058             this->deleteSync(cb.fSync);
4059         }
4060         fFinishCallbacks.clear();
4061         if (info.fFinishedProc) {
4062             info.fFinishedProc(info.fFinishedContext);
4063         }
4064     } else {
4065         if (info.fFinishedProc) {
4066             FinishCallback callback;
4067             callback.fCallback = info.fFinishedProc;
4068             callback.fContext = info.fFinishedContext;
4069             callback.fSync = (GrGLsync)this->insertFence();
4070             fFinishCallbacks.push_back(callback);
4071             GL_CALL(Flush());
4072         } else if (insertedSemaphore) {
4073             // Must call flush after semaphores in case they are waited on another GL context.
4074             GL_CALL(Flush());
4075         }
4076         // See if any previously inserted finish procs are good to go.
4077         this->checkFinishProcs();
4078     }
4079     return true;
4080 }
4081 
submit(GrOpsRenderPass * renderPass)4082 void GrGLGpu::submit(GrOpsRenderPass* renderPass) {
4083     // The GrGLOpsRenderPass doesn't buffer ops so there is nothing to do here
4084     SkASSERT(fCachedOpsRenderPass.get() == renderPass);
4085     fCachedOpsRenderPass->reset();
4086 }
4087 
insertFence()4088 GrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() {
4089     SkASSERT(this->caps()->fenceSyncSupport());
4090     GrGLsync sync;
4091     if (this->glCaps().fenceType() == GrGLCaps::FenceType::kNVFence) {
4092         static_assert(sizeof(GrGLsync) >= sizeof(GrGLuint));
4093         GrGLuint fence = 0;
4094         GL_CALL(GenFences(1, &fence));
4095         GL_CALL(SetFence(fence, GR_GL_ALL_COMPLETED));
4096         sync = reinterpret_cast<GrGLsync>(static_cast<intptr_t>(fence));
4097     } else {
4098         GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
4099     }
4100     static_assert(sizeof(GrFence) >= sizeof(GrGLsync));
4101     return (GrFence)sync;
4102 }
4103 
waitSync(GrGLsync sync,uint64_t timeout,bool flush)4104 bool GrGLGpu::waitSync(GrGLsync sync, uint64_t timeout, bool flush) {
4105     if (this->glCaps().fenceType() == GrGLCaps::FenceType::kNVFence) {
4106         GrGLuint nvFence = static_cast<GrGLuint>(reinterpret_cast<intptr_t>(sync));
4107         if (!timeout) {
4108             if (flush) {
4109                 GL_CALL(Flush);
4110             }
4111             GrGLboolean result;
4112             GL_CALL_RET(result, TestFence(nvFence));
4113             return result == GR_GL_TRUE;
4114         }
4115         // Ignore non-zero timeouts. GL_NV_fence has no timeout functionality.
4116         // If this really becomes necessary we could poll TestFence().
4117         // FinishFence always flushes so no need to check flush param.
4118         GL_CALL(FinishFence(nvFence));
4119         return true;
4120     } else {
4121         GrGLbitfield flags = flush ? GR_GL_SYNC_FLUSH_COMMANDS_BIT : 0;
4122         GrGLenum result;
4123         GL_CALL_RET(result, ClientWaitSync(sync, flags, timeout));
4124         return (GR_GL_CONDITION_SATISFIED == result || GR_GL_ALREADY_SIGNALED == result);
4125     }
4126 }
4127 
waitFence(GrFence fence,uint64_t timeout)4128 bool GrGLGpu::waitFence(GrFence fence, uint64_t timeout) {
4129     return this->waitSync((GrGLsync)fence, timeout, /* flush = */ true);
4130 }
4131 
deleteFence(GrFence fence) const4132 void GrGLGpu::deleteFence(GrFence fence) const {
4133     this->deleteSync((GrGLsync)fence);
4134 }
4135 
makeSemaphore(bool isOwned)4136 std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT GrGLGpu::makeSemaphore(bool isOwned) {
4137     SkASSERT(this->caps()->semaphoreSupport());
4138     return GrGLSemaphore::Make(this, isOwned);
4139 }
4140 
wrapBackendSemaphore(const GrBackendSemaphore & semaphore,GrResourceProvider::SemaphoreWrapType wrapType,GrWrapOwnership ownership)4141 std::unique_ptr<GrSemaphore> GrGLGpu::wrapBackendSemaphore(
4142         const GrBackendSemaphore& semaphore,
4143         GrResourceProvider::SemaphoreWrapType wrapType,
4144         GrWrapOwnership ownership) {
4145     SkASSERT(this->caps()->semaphoreSupport());
4146     return GrGLSemaphore::MakeWrapped(this, semaphore.glSync(), ownership);
4147 }
4148 
insertSemaphore(GrSemaphore * semaphore)4149 void GrGLGpu::insertSemaphore(GrSemaphore* semaphore) {
4150     GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore);
4151 
4152     GrGLsync sync;
4153     GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
4154     glSem->setSync(sync);
4155 }
4156 
waitSemaphore(GrSemaphore * semaphore)4157 void GrGLGpu::waitSemaphore(GrSemaphore* semaphore) {
4158     GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore);
4159 
4160     GL_CALL(WaitSync(glSem->sync(), 0, GR_GL_TIMEOUT_IGNORED));
4161 }
4162 
checkFinishProcs()4163 void GrGLGpu::checkFinishProcs() {
4164     // Bail after the first unfinished sync since we expect they signal in the order inserted.
4165     while (!fFinishCallbacks.empty() && this->waitSync(fFinishCallbacks.front().fSync,
4166                                                        /* timeout = */ 0, /* flush  = */ false)) {
4167         fFinishCallbacks.front().fCallback(fFinishCallbacks.front().fContext);
4168         this->deleteSync(fFinishCallbacks.front().fSync);
4169         fFinishCallbacks.pop_front();
4170     }
4171 }
4172 
deleteSync(GrGLsync sync) const4173 void GrGLGpu::deleteSync(GrGLsync sync) const {
4174     if (this->glCaps().fenceType() == GrGLCaps::FenceType::kNVFence) {
4175         GrGLuint nvFence = SkToUInt(reinterpret_cast<intptr_t>(sync));
4176         GL_CALL(DeleteFences(1, &nvFence));
4177     } else {
4178         GL_CALL(DeleteSync(sync));
4179     }
4180 }
4181 
prepareTextureForCrossContextUsage(GrTexture * texture)4182 std::unique_ptr<GrSemaphore> GrGLGpu::prepareTextureForCrossContextUsage(GrTexture* texture) {
4183     // Set up a semaphore to be signaled once the data is ready, and flush GL
4184     std::unique_ptr<GrSemaphore> semaphore = this->makeSemaphore(true);
4185     SkASSERT(semaphore);
4186     this->insertSemaphore(semaphore.get());
4187     // We must call flush here to make sure the GrGLSync object gets created and sent to the gpu.
4188     GL_CALL(Flush());
4189 
4190     return semaphore;
4191 }
4192 
TextureToCopyProgramIdx(GrTexture * texture)4193 int GrGLGpu::TextureToCopyProgramIdx(GrTexture* texture) {
4194     switch (GrSLCombinedSamplerTypeForTextureType(texture->texturePriv().textureType())) {
4195         case kTexture2DSampler_GrSLType:
4196             return 0;
4197         case kTexture2DRectSampler_GrSLType:
4198             return 1;
4199         case kTextureExternalSampler_GrSLType:
4200             return 2;
4201         default:
4202             SK_ABORT("Unexpected samper type");
4203     }
4204 }
4205 
4206 #ifdef SK_ENABLE_DUMP_GPU
4207 #include "src/utils/SkJSONWriter.h"
onDumpJSON(SkJSONWriter * writer) const4208 void GrGLGpu::onDumpJSON(SkJSONWriter* writer) const {
4209     // We are called by the base class, which has already called beginObject(). We choose to nest
4210     // all of our caps information in a named sub-object.
4211     writer->beginObject("GL GPU");
4212 
4213     const GrGLubyte* str;
4214     GL_CALL_RET(str, GetString(GR_GL_VERSION));
4215     writer->appendString("GL_VERSION", (const char*)(str));
4216     GL_CALL_RET(str, GetString(GR_GL_RENDERER));
4217     writer->appendString("GL_RENDERER", (const char*)(str));
4218     GL_CALL_RET(str, GetString(GR_GL_VENDOR));
4219     writer->appendString("GL_VENDOR", (const char*)(str));
4220     GL_CALL_RET(str, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
4221     writer->appendString("GL_SHADING_LANGUAGE_VERSION", (const char*)(str));
4222 
4223     writer->appendName("extensions");
4224     glInterface()->fExtensions.dumpJSON(writer);
4225 
4226     writer->endObject();
4227 }
4228 #endif
4229