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