1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 839edf7664f50b6c890b933b5bbed67a8735b349bjvanverth#include "GrGLGpu.h" 995e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary 1095e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "../private/GrGLSL.h" 1195e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "GrFixedClip.h" 12397536cabe12a9936659870dd220c869789424bacdalton#include "GrGLBuffer.h" 13066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrGLGpuCommandBuffer.h" 146be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel#include "GrGLSemaphore.h" 158dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel#include "GrGLStencilAttachment.h" 1637dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon#include "GrGLTextureRenderTarget.h" 173582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h" 180e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel#include "GrMesh.h" 1995e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "GrPipeline.h" 206bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTargetPriv.h" 2194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "GrShaderCaps.h" 22afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrSurfacePriv.h" 233798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips#include "GrSurfaceProxyPriv.h" 24afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrTexturePriv.h" 25ef3913bcbff265ff86116ae4f3dd2768dc42cccasenorblanco@chromium.org#include "GrTypes.h" 2695e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkAutoMalloc.h" 2718b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner#include "SkMakeUnique.h" 2855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkMipMap.h" 2955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkPixmap.h" 30c456b73fef9589bbdc5eb83eaa83e53c357bb3daKevin Lubick#include "SkSLCompiler.h" 3195e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkStrokeRec.h" 323582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com#include "SkTemplates.h" 3355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkTypes.h" 3495e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "builders/GrGLShaderStringBuilder.h" 3595e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "instanced/GLInstancedRendering.h" 36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 370b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) 3856bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) 390b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com 40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#define SKIP_CACHE_CHECK true 41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 424f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com#if GR_GL_CHECK_ALLOC_WITH_GET_ERROR 434f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) 444f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) 454f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) 46fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#else 474f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com #define CLEAR_ERROR_BEFORE_ALLOC(iface) 484f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call) 494f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR 504f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com#endif 514f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com 5232ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth//#define USE_NSIGHT 5332ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth 544bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com/////////////////////////////////////////////////////////////////////////////// 554bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com 56a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonusing gr_instanced::InstancedRendering; 57a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonusing gr_instanced::GLInstancedRendering; 58b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 598917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonstatic const GrGLenum gXfermodeEquation2Blend[] = { 608917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton // Basic OpenGL blend equations. 618917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_FUNC_ADD, 628917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_FUNC_SUBTRACT, 638917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_FUNC_REVERSE_SUBTRACT, 648917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton 658917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton // GL_KHR_blend_equation_advanced. 668917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_SCREEN, 678917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_OVERLAY, 688917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_DARKEN, 698917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_LIGHTEN, 708917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_COLORDODGE, 718917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_COLORBURN, 728917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_HARDLIGHT, 738917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_SOFTLIGHT, 748917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_DIFFERENCE, 758917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_EXCLUSION, 768917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_MULTIPLY, 778917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_HSL_HUE, 788917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_HSL_SATURATION, 798917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_HSL_COLOR, 808917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GR_GL_HSL_LUMINOSITY 818917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton}; 828917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(0 == kAdd_GrBlendEquation); 838917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation); 848917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation); 858917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(3 == kScreen_GrBlendEquation); 868917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(4 == kOverlay_GrBlendEquation); 878917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(5 == kDarken_GrBlendEquation); 888917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(6 == kLighten_GrBlendEquation); 898917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(7 == kColorDodge_GrBlendEquation); 908917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(8 == kColorBurn_GrBlendEquation); 918917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(9 == kHardLight_GrBlendEquation); 928917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(10 == kSoftLight_GrBlendEquation); 938917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(11 == kDifference_GrBlendEquation); 948917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(12 == kExclusion_GrBlendEquation); 958917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(13 == kMultiply_GrBlendEquation); 968917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(14 == kHSLHue_GrBlendEquation); 978917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(15 == kHSLSaturation_GrBlendEquation); 988917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(16 == kHSLColor_GrBlendEquation); 998917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(17 == kHSLLuminosity_GrBlendEquation); 100f7cc87719e53df86784d0d953b88c45a3be38953bsalomonGR_STATIC_ASSERT(SK_ARRAY_COUNT(gXfermodeEquation2Blend) == kGrBlendEquationCnt); 1018917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton 1020f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.comstatic const GrGLenum gXfermodeCoeff2Blend[] = { 1030f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ZERO, 1040f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ONE, 1050f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_SRC_COLOR, 1060f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ONE_MINUS_SRC_COLOR, 1070f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_DST_COLOR, 1080f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ONE_MINUS_DST_COLOR, 1090f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_SRC_ALPHA, 1100f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ONE_MINUS_SRC_ALPHA, 1110f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_DST_ALPHA, 1120f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ONE_MINUS_DST_ALPHA, 1130f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_CONSTANT_COLOR, 1140f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ONE_MINUS_CONSTANT_COLOR, 1150f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_CONSTANT_ALPHA, 1160f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_ONE_MINUS_CONSTANT_ALPHA, 117271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com 118271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com // extended blend coeffs 119271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com GR_GL_SRC1_COLOR, 120271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com GR_GL_ONE_MINUS_SRC1_COLOR, 121271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com GR_GL_SRC1_ALPHA, 122271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com GR_GL_ONE_MINUS_SRC1_ALPHA, 123ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}; 124ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 125861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonbool GrGLGpu::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { 126080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com static const bool gCoeffReferencesBlendConst[] = { 127080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 128080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 129080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 130080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 131080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 132080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 133080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 134080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 135080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 136080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com false, 137080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com true, 138080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com true, 139080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com true, 140080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com true, 141271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com 142271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com // extended blend coeffs 143271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com false, 144271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com false, 145271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com false, 146271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com false, 147080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com }; 148080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com return gCoeffReferencesBlendConst[coeff]; 149f7cc87719e53df86784d0d953b88c45a3be38953bsalomon GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendConst)); 15047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com 15147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff); 15247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff); 15347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff); 15447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff); 15547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff); 15647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff); 15747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff); 15847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff); 15947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff); 16047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff); 16147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff); 16247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff); 16347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff); 16447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff); 16547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com 16647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff); 16747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff); 16847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff); 16947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff); 170271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com 171271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope 172f7cc87719e53df86784d0d953b88c45a3be38953bsalomon GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gXfermodeCoeff2Blend)); 173080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com} 174080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com 175ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 177ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 178682c269a1511200322916af83053e26004c0ec40bsalomonGrGpu* GrGLGpu::Create(GrBackendContext backendContext, const GrContextOptions& options, 179682c269a1511200322916af83053e26004c0ec40bsalomon GrContext* context) { 180144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary sk_sp<const GrGLInterface> glInterface( 181424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon reinterpret_cast<const GrGLInterface*>(backendContext)); 182424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon if (!glInterface) { 183424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon glInterface.reset(GrGLDefaultInterface()); 184424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon } else { 185424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon glInterface->ref(); 186424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon } 187424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon if (!glInterface) { 18896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 189424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon } 190144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary GrGLContext* glContext = GrGLContext::Create(glInterface.get(), options); 191424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon if (glContext) { 192385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GrGLGpu(glContext, context); 193424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon } 19496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 195424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon} 196424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon 197e38160c38c295a4d9cd2441727ebdc6e5f47e225rileya@google.comstatic bool gPrintStartupSpew; 19842ab7ea76e57ae1abaf98258ecd159f60c36b3babsalomon@google.com 199424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomonGrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) 2006e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com : GrGpu(context) 201e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fGLContext(ctx) 202e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fProgramCache(new ProgramCache(this)) 203e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fHWProgramID(0) 204e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fTempSrcFBOID(0) 205e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fTempDstFBOID(0) 206e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fStencilClearFBOID(0) 20774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton , fHWMaxUsedBufferTextureUnit(-1) 208e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fHWMinSampleShading(0.0) { 209e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { 210e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fCopyPrograms[i].fProgram = 0; 211e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 21233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { 21333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fMipmapPrograms[i].fProgram = 0; 21433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 215e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fWireRectProgram.fProgram = 0; 216e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 217424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon SkASSERT(ctx); 218424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon fCaps.reset(SkRef(ctx->caps())); 219bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com 2201edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon fHWBoundTextureUniqueIDs.reset(this->caps()->shaderCaps()->maxCombinedSamplers()); 2211edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon fHWBoundImageStorages.reset(this->caps()->shaderCaps()->maxCombinedImageStorages()); 222a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org 223e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER; 224e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER; 225e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kTexel_GrBufferType].fGLTarget = GR_GL_TEXTURE_BUFFER; 226e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kDrawIndirect_GrBufferType].fGLTarget = GR_GL_DRAW_INDIRECT_BUFFER; 227e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (GrGLCaps::kChromium_TransferBufferType == this->glCaps().transferBufferType()) { 228e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = 229e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM; 230e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = 231e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM; 232e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } else { 233e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = GR_GL_PIXEL_UNPACK_BUFFER; 234e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = GR_GL_PIXEL_PACK_BUFFER; 235e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 236e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState)); 237e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 23874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (this->caps()->shaderCaps()->texelBufferSupport()) { 2391edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon fHWBufferTextures.reset(this->caps()->shaderCaps()->maxCombinedSamplers()); 24074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 24174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 242e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 243e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fPathRendering.reset(new GrGLPathRendering(this)); 244e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 245e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 246424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon GrGLClearErr(this->glInterface()); 247eeeb5a05b900df80feded719b4a3181fce0ac1b4reed@google.com if (gPrintStartupSpew) { 24856bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com const GrGLubyte* vendor; 24956bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com const GrGLubyte* renderer; 25056bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com const GrGLubyte* version; 25156bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com GL_CALL_RET(vendor, GetString(GR_GL_VENDOR)); 25256bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com GL_CALL_RET(renderer, GetString(GR_GL_RENDERER)); 25356bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com GL_CALL_RET(version, GetString(GR_GL_VERSION)); 254861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon SkDebugf("------------------------- create GrGLGpu %p --------------\n", 255eeeb5a05b900df80feded719b4a3181fce0ac1b4reed@google.com this); 25638406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("------ VENDOR %s\n", vendor); 25738406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("------ RENDERER %s\n", renderer); 25838406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("------ VERSION %s\n", version); 25938406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("------ EXTENSIONS\n"); 260424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon this->glContext().extensions().print(); 26138406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("\n"); 262297aaf97a32ac16a2bc3f4bbc231d5de859ac02dkkinnunen SkDebugf("%s", this->glCaps().dump().c_str()); 263eeeb5a05b900df80feded719b4a3181fce0ac1b4reed@google.com } 26418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com} 26518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com 266861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonGrGLGpu::~GrGLGpu() { 267e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton // Ensure any GrGpuResource objects get deleted first, since they may require a working GrGLGpu 268e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton // to release the resources held by the objects themselves. 269702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fPathRendering.reset(); 270e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fCopyProgramArrayBuffer.reset(); 27133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fMipmapProgramArrayBuffer.reset(); 272e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fWireRectArrayBuffer.reset(); 273702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen 2749ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com if (0 != fHWProgramID) { 2755739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com // detach the current program so there is no confusion on OpenGL's part 2765739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com // that we want it to be deleted 2775739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com GL_CALL(UseProgram(0)); 2785739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com } 2795739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com 280d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (0 != fTempSrcFBOID) { 281d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); 2820f5f967f6777612353c762e6d0095f733adfb326egdaniel } 283d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (0 != fTempDstFBOID) { 284d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); 2850f5f967f6777612353c762e6d0095f733adfb326egdaniel } 286d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (0 != fStencilClearFBOID) { 287d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); 288dd3143b0079f01980ca4886f00c39b3caa3fee6absalomon } 2890f5f967f6777612353c762e6d0095f733adfb326egdaniel 2907ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { 2917ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon if (0 != fCopyPrograms[i].fProgram) { 2927ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); 2937ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 2946df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 2956dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 29633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { 29733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (0 != fMipmapPrograms[i].fProgram) { 29833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram)); 29933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 30033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 30133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 3026dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon if (0 != fWireRectProgram.fProgram) { 3036dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); 3046dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon } 3056dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 306c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com delete fProgramCache; 307c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon} 308c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon 3096e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomonvoid GrGLGpu::disconnect(DisconnectType type) { 3106e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon INHERITED::disconnect(type); 3116e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (DisconnectType::kCleanup == type) { 3126e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (fHWProgramID) { 3136e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon GL_CALL(UseProgram(0)); 3146e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3156e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (fTempSrcFBOID) { 3166e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); 3176e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3186e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (fTempDstFBOID) { 3196e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); 3206e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3216e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (fStencilClearFBOID) { 3226e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); 3236e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3246e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { 3256e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (fCopyPrograms[i].fProgram) { 3266e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); 3276e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3286e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 32933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { 33033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (fMipmapPrograms[i].fProgram) { 33133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram)); 33233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 33333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 3346e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (fWireRectProgram.fProgram) { 3356e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); 3366e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3376e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } else { 3386e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon if (fProgramCache) { 3396e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon fProgramCache->abandon(); 3406e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3416e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon } 3426e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon 3436e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon delete fProgramCache; 3446e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon fProgramCache = nullptr; 3456e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon 346c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon fHWProgramID = 0; 347d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fTempSrcFBOID = 0; 348d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fTempDstFBOID = 0; 349d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fStencilClearFBOID = 0; 350e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fCopyProgramArrayBuffer.reset(); 3517ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { 3527ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon fCopyPrograms[i].fProgram = 0; 3537ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 35433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fMipmapProgramArrayBuffer.reset(); 35533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { 35633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fMipmapPrograms[i].fProgram = 0; 35733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 3586dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon fWireRectProgram.fProgram = 0; 359e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fWireRectArrayBuffer.reset(); 360e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 3616e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon this->glPathRendering()->disconnect(type); 362c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon } 36318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com} 36418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com 36518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 366a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 367861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::onResetContext(uint32_t resetBits) { 3685aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com // we don't use the zb at all 3690a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kMisc_GrGLBackendState) { 3700a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_DEPTH_TEST)); 3710a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(DepthMask(GR_GL_FALSE)); 3720a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com 373e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kTexel_GrBufferType].invalidate(); 374e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kDrawIndirect_GrBufferType].invalidate(); 375e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kXferCpuToGpu_GrBufferType].invalidate(); 376e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kXferGpuToCpu_GrBufferType].invalidate(); 377c161310ffdbbcb3b023da2e375faefd211fa52e8cdalton 3785fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips fHWDrawFace = GrDrawFace::kInvalid; 3799e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org if (kGL_GrGLStandard == this->glStandard()) { 38032ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#ifndef USE_NSIGHT 3810a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // Desktop-only state that we never change 3820a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (!this->glCaps().isCoreProfile()) { 3830a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_POINT_SMOOTH)); 3840a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_LINE_SMOOTH)); 3850a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_POLYGON_SMOOTH)); 3860a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_POLYGON_STIPPLE)); 3870a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP)); 3880a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP)); 3890a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 3900a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a 3910a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // core profile. This seems like a bug since the core spec removes any mention of 3920a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // GL_ARB_imaging. 3930a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) { 3940a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_COLOR_TABLE)); 3950a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 3960a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL)); 39732ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#endif 3980a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // Since ES doesn't support glPointSize at all we always use the VS to 3990a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // set the point size 4000a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE)); 4010a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com 4020a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // We should set glPolygonMode(FRONT_AND_BACK,FILL) here, too. It isn't 4030a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // currently part of our gl interface. There are probably others as 4040a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // well. 405ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com } 4065816233d237e5c214f14f1c92eda4a87c898ea11joshualitt 4075816233d237e5c214f14f1c92eda4a87c898ea11joshualitt if (kGLES_GrGLStandard == this->glStandard() && 408424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon this->hasExtension("GL_ARM_shader_framebuffer_fetch")) { 4095816233d237e5c214f14f1c92eda4a87c898ea11joshualitt // The arm extension requires specifically enabling MSAA fetching per sample. 4105816233d237e5c214f14f1c92eda4a87c898ea11joshualitt // On some devices this may have a perf hit. Also multiple render targets are disabled 4115816233d237e5c214f14f1c92eda4a87c898ea11joshualitt GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM)); 4125816233d237e5c214f14f1c92eda4a87c898ea11joshualitt } 4130a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fHWWriteToColor = kUnknown_TriState; 4140a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // we only ever use lines in hairline mode 4150a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(LineWidth(1)); 416aca31fea8ca620bfdb2887641b7ba56e401a72d7bsalomon GL_CALL(Disable(GR_GL_DITHER)); 417b65e0cb8ad8a690498142d2b0097be250b0c7dfbtwiz@google.com } 418d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 419b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel if (resetBits & kMSAAEnable_GrGLBackendState) { 420b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel fMSAAEnabled = kUnknown_TriState; 421dded69693dd3779f081326cde24c3954505b129dvbuzinov 422eed519e6a2d0e61b0733a388de9320af897ed197egdaniel if (this->caps()->usesMixedSamples()) { 423af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton if (0 != this->caps()->maxRasterSamples()) { 424af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton fHWRasterMultisampleEnabled = kUnknown_TriState; 425af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton fHWNumRasterSamples = 0; 426af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } 427af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton 428af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton // The skia blend modes all use premultiplied alpha and therefore expect RGBA coverage 429af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton // modulation. This state has no effect when not rendering to a mixed sampled target. 430dded69693dd3779f081326cde24c3954505b129dvbuzinov GL_CALL(CoverageModulation(GR_GL_RGBA)); 431dded69693dd3779f081326cde24c3954505b129dvbuzinov } 4320a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 433ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 43446fbfe0cd1bbe60fd15ce52e784f5d51450ff5fdcommit-bot@chromium.org fHWActiveTextureUnitIdx = -1; // invalid 43546fbfe0cd1bbe60fd15ce52e784f5d51450ff5fdcommit-bot@chromium.org 4360a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kTextureBinding_GrGLBackendState) { 4371c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) { 438294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundTextureUniqueIDs[s].makeInvalid(); 4390a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 44074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton for (int b = 0; b < fHWBufferTextures.count(); ++b) { 44174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton SkASSERT(this->caps()->shaderCaps()->texelBufferSupport()); 44274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton fHWBufferTextures[b].fKnownBound = false; 44374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 444f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon for (int i = 0; i < fHWBoundImageStorages.count(); ++i) { 4458b7a7ddea344eed96f095652359c5c86349f86d0Brian Salomon SkASSERT(this->caps()->shaderCaps()->imageLoadStoreSupport()); 446f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fHWBoundImageStorages[i].fTextureUniqueID.makeInvalid(); 447f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon } 448cad107bbe723e5e71e625dccb5d7bcfe20c55c58bsalomon@google.com } 449ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4500a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kBlend_GrGLBackendState) { 4510a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fHWBlendState.invalidate(); 4520a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 453730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com 4540a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kView_GrGLBackendState) { 4550a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fHWScissorSettings.invalidate(); 456bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton fHWWindowRectsState.invalidate(); 4570a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fHWViewport.invalidate(); 4580a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 459ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4600a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kStencil_GrGLBackendState) { 4610a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fHWStencilSettings.invalidate(); 4620a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fHWStencilTestEnabled = kUnknown_TriState; 4630a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 4648ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com 4650a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com // Vertex 4660a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kVertex_GrGLBackendState) { 467e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWVertexArrayState.invalidate(); 468e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kVertex_GrBufferType].invalidate(); 469e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWBufferState[kIndex_GrBufferType].invalidate(); 4700a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 471ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com 4720a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kRenderTarget_GrGLBackendState) { 473294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 47416921ec30a81976129d507b1148c93a322e61a4fbsalomon fHWSRGBFramebuffer = kUnknown_TriState; 4750a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 476ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com 4770a6fe71f1bc0e601b41b7ae6d28b8c96a2c41116commit-bot@chromium.org if (resetBits & kPathRendering_GrGLBackendState) { 478e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth if (this->caps()->shaderCaps()->pathRenderingSupport()) { 479ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->glPathRendering()->resetContext(); 4800a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 48105a718c9d2302b08f859adac5854b2df6ff84e43bsalomon@google.com } 482ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 4838ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com // we assume these values 4840a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kPixelStore_GrGLBackendState) { 4850a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (this->glCaps().unpackRowLengthSupport()) { 4860a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 4870a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 4880a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (this->glCaps().packRowLengthSupport()) { 4890a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 4900a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 4910a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (this->glCaps().unpackFlipYSupport()) { 4920a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 4930a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 4940a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (this->glCaps().packFlipYSupport()) { 4950a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE)); 4960a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 497ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com } 498ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com 4990a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com if (resetBits & kProgram_GrGLBackendState) { 5000a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fHWProgramID = 0; 5010a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com } 502ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 503ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 504cf614fd48e38f7c544e666dd19a5a81c35830ba3egdanielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin, bool renderTarget) { 5053cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // By default, GrRenderTargets are GL's normal orientation so that they 5063cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // can be drawn to by the outside world without the client having 5073cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // to render upside down. 5083cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (kDefault_GrSurfaceOrigin == origin) { 5093cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org return renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin; 5103cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org } else { 5113cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org return origin; 5123cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org } 5133cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org} 5143cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org 5156bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc, 5166bd5284415bd983b0628c4941dff5def40018f5abungeman GrWrapOwnership ownership) { 517091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon const GrGLTextureInfo* info = reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle); 518091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon if (!info || !info->fID) { 51996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 520b72e5d31383464171c01370c09cdbba77707e8efrobertphillips@google.com } 521b72e5d31383464171c01370c09cdbba77707e8efrobertphillips@google.com 5227ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon // next line relies on GrBackendTextureDesc's flags matching GrTexture's 5237ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag); 524766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman SkASSERT(!renderTarget || kAdoptAndCache_GrWrapOwnership != ownership); // Not supported 5257ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon 526b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GrGLTexture::IDDesc idDesc; 527091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon idDesc.fInfo = *info; 528e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon 5297ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon if (GR_GL_TEXTURE_EXTERNAL == idDesc.fInfo.fTarget) { 5307ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon if (renderTarget) { 5317ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon // This combination is not supported. 5327ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon return nullptr; 5337ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 5341edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (!this->caps()->shaderCaps()->externalTextureSupport()) { 5357ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon return nullptr; 5367ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 537e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon } else if (GR_GL_TEXTURE_RECTANGLE == idDesc.fInfo.fTarget) { 538e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon if (!this->glCaps().rectangleTextureSupport()) { 539e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon return nullptr; 540e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon } 541e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon } else if (GR_GL_TEXTURE_2D != idDesc.fInfo.fTarget) { 542e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon return nullptr; 5437ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 544e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon 545e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon // Sample count is interpreted to mean the number of samples that Gr code should allocate 546a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon // for a render buffer that resolves to the texture. We don't support MSAA textures. 547a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon if (desc.fSampleCnt && !renderTarget) { 548a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon return nullptr; 549a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon } 55010528f1d5838ae1cac015024c4e8731484f888d1bsalomon 551766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman if (kBorrow_GrWrapOwnership == ownership) { 552a6953f2a079a64848499709b9c635405f53566e3Brian Osman idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed; 553766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman } else { 554766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman idDesc.fOwnership = GrBackendObjectOwnership::kOwned; 555e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon } 556b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon 55718b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner GrSurfaceDesc surfDesc; 558b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; 559b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon surfDesc.fWidth = desc.fWidth; 560b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon surfDesc.fHeight = desc.fHeight; 561b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon surfDesc.fConfig = desc.fConfig; 56294e50100eb747b2dfd659bacc9cf4246f6f20278senorblanco surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()); 5633cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // FIXME: this should be calling resolve_origin(), but Chrome code is currently 5643cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // assuming the old behaviour, which is that backend textures are always 5653cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to: 5663cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); 5673cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (kDefault_GrSurfaceOrigin == desc.fOrigin) { 568b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; 5693cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org } else { 570b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon surfDesc.fOrigin = desc.fOrigin; 5713cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org } 572e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 5733cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (renderTarget) { 574b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GrGLRenderTarget::IDDesc rtIDDesc; 5752e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) { 57696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 577e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com } 5786bd5284415bd983b0628c4941dff5def40018f5abungeman return GrGLTextureRenderTarget::MakeWrapped(this, surfDesc, idDesc, rtIDDesc); 579e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com } 580766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman 581766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman if (kAdoptAndCache_GrWrapOwnership == ownership) { 582766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman return sk_sp<GrTexture>(new GrGLTexture(this, SkBudgeted::kYes, surfDesc, idDesc)); 583766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman } else { 584766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman return GrGLTexture::MakeWrapped(this, surfDesc, idDesc); 585766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman } 586e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 587e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 5880b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osmansk_sp<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc){ 589b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GrGLRenderTarget::IDDesc idDesc; 590d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); 591b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon idDesc.fMSColorRenderbufferID = 0; 592d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 5930b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman idDesc.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed; 594f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton idDesc.fIsMixedSampled = false; 595b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon 596b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GrSurfaceDesc desc; 597b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon desc.fConfig = wrapDesc.fConfig; 5984b013296bf67df6c8d119a8f5a2b3dd6530c0b6fsenorblanco desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; 599b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon desc.fWidth = wrapDesc.fWidth; 600b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon desc.fHeight = wrapDesc.fHeight; 60194e50100eb747b2dfd659bacc9cf4246f6f20278senorblanco desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()); 602b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); 603b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon 6046bd5284415bd983b0628c4941dff5def40018f5abungeman return GrGLRenderTarget::MakeWrapped(this, desc, idDesc, wrapDesc.fStencilBits); 605e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 606e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 6076bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc){ 608f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk const GrGLTextureInfo* info = reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle); 609f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk if (!info || !info->fID) { 610f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk return nullptr; 611f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk } 612f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk 613db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth GrGLTextureInfo texInfo; 614db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth texInfo = *info; 615f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk 616db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth if (GR_GL_TEXTURE_RECTANGLE != texInfo.fTarget && 617db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth GR_GL_TEXTURE_2D != texInfo.fTarget) { 618f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk // Only texture rectangle and texture 2d are supported. We do not check whether texture 619f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk // rectangle is supported by Skia - if the caller provided us with a texture rectangle, 620f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk // we assume the necessary support exists. 621f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk return nullptr; 622f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk } 623f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk 62418b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner GrSurfaceDesc surfDesc; 625f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; 626f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk surfDesc.fWidth = desc.fWidth; 627f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk surfDesc.fHeight = desc.fHeight; 628f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk surfDesc.fConfig = desc.fConfig; 629f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()); 630f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk // FIXME: this should be calling resolve_origin(), but Chrome code is currently 631f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk // assuming the old behaviour, which is that backend textures are always 632f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to: 633f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); 634f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk if (kDefault_GrSurfaceOrigin == desc.fOrigin) { 635f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; 636f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk } else { 637f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk surfDesc.fOrigin = desc.fOrigin; 638f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk } 639f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk 640f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk GrGLRenderTarget::IDDesc rtIDDesc; 641db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) { 642f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk return nullptr; 643f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk } 6446bd5284415bd983b0628c4941dff5def40018f5abungeman return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0); 645f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk} 646f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk 64771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 648f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk 649f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomonbool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 650ed828001da75f4a3a5d31d9f1c1935e3595ce920cblume GrPixelConfig srcConfig, 651f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon DrawPreference* drawPreference, 652f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon WritePixelTempDrawInfo* tempDrawInfo) { 653d0be1ef36c64c2a420cbd82f4c033704d4c54a07Brian Osman if (GrPixelConfigIsCompressed(dstSurface->config())) { 654f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon return false; 655f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon } 656f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon 6576cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon // This subclass only allows writes to textures. If the dst is not a texture we have to draw 6586cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon // into it. We could use glDrawPixels on GLs that have it, but we don't today. 6596cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon if (!dstSurface->asTexture()) { 6606cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 6617ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } else { 6627ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon GrGLTexture* texture = static_cast<GrGLTexture*>(dstSurface->asTexture()); 663e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon if (GR_GL_TEXTURE_EXTERNAL == texture->target()) { 664e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon // We don't currently support writing pixels to EXTERNAL textures. 6657ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon return false; 6667ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 6676cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon } 6686cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon 66916921ec30a81976129d507b1148c93a322e61a4fbsalomon if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConfig)) { 67016921ec30a81976129d507b1148c93a322e61a4fbsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 67116921ec30a81976129d507b1148c93a322e61a4fbsalomon } 67216921ec30a81976129d507b1148c93a322e61a4fbsalomon 6736c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon // Start off assuming no swizzling 6746c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); 6756c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fWriteConfig = srcConfig; 676f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon 677f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon // These settings we will always want if a temp draw is performed. Initially set the config 678f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon // to srcConfig, though that may be modified if we decide to do a R/G swap. 679f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags; 680f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 681f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fWidth = width; 682f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fHeight = height; 683f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 684f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. 685f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon 686f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config(); 687f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon 688f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon if (configsAreRBSwaps) { 689f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon if (!this->caps()->isConfigTexturable(srcConfig)) { 690f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 691f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 6926c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 6936c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fWriteConfig = dstSurface->config(); 69488c7b988ba7792e51e741567426069cd9cc852ddbsalomon } else if (this->glCaps().rgba8888PixelsOpsAreSlow() && 69588c7b988ba7792e51e741567426069cd9cc852ddbsalomon kRGBA_8888_GrPixelConfig == srcConfig) { 696f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 697f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 6986c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 6996c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fWriteConfig = dstSurface->config(); 700f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon } else if (kGLES_GrGLStandard == this->glStandard() && 701f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon this->glCaps().bgraIsInternalFormat()) { 702f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon // The internal format and external formats must match texture uploads so we can't 703f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon // swizzle while uploading when BGRA is a distinct internal format. 704f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 705f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 7066c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 7076c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fWriteConfig = dstSurface->config(); 708f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon } 709f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon } 710f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon 711f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon if (!this->glCaps().unpackFlipYSupport() && 712f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) { 713f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 714f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon } 715f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon 716f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon return true; 717f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon} 71871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com 71917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverthstatic bool check_write_and_transfer_input(GrGLTexture* glTex, GrSurface* surface, 72017aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth GrPixelConfig config) { 7216cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon if (!glTex) { 7226cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon return false; 7236cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon } 724280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com 72516921ec30a81976129d507b1148c93a322e61a4fbsalomon // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels. 72616921ec30a81976129d507b1148c93a322e61a4fbsalomon if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 72716921ec30a81976129d507b1148c93a322e61a4fbsalomon return false; 72816921ec30a81976129d507b1148c93a322e61a4fbsalomon } 72916921ec30a81976129d507b1148c93a322e61a4fbsalomon 730e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textures 731e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) { 7327ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon return false; 7337ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 7347ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon 73517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth return true; 73617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth} 73717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 73817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverthbool GrGLGpu::onWritePixels(GrSurface* surface, 73917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth int left, int top, int width, int height, 74055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrPixelConfig config, 74155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels) { 74217aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 74317aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 74417aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth if (!check_write_and_transfer_input(glTex, surface, config)) { 74517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth return false; 74617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth } 74717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 748a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org this->setScratchTextureUnit(); 74910528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 7506f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 751145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski bool success = false; 752b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 753861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixels() 754b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon SkASSERT(config == glTex->desc().fConfig); 75555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), texels, 75617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth kWrite_UploadType, left, top, width, height); 757145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski } else { 758e7d7f90b59b15a291c113b449f5c6ac57f8d1aacjcgregorio success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_UploadType, 75955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume left, top, width, height, config, texels); 760cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org } 761145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski 76255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume return success; 7636f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 7649d6cfd80a06e5efde1fc865c5e65c0ad27389a3fbsalomon@google.com 765c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverthbool GrGLGpu::onTransferPixels(GrSurface* surface, 76617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth int left, int top, int width, int height, 767397536cabe12a9936659870dd220c869789424bacdalton GrPixelConfig config, GrBuffer* transferBuffer, 76817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth size_t offset, size_t rowBytes) { 769c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 77017aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 771c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth if (!check_write_and_transfer_input(glTex, surface, config)) { 77217aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth return false; 77317aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth } 77417aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 77517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth // For the moment, can't transfer compressed data 77617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 77717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth return false; 77817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth } 77917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 78017aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth this->setScratchTextureUnit(); 78117aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 78217aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 783397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(!transferBuffer->isMapped()); 784397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(!transferBuffer->isCPUBacked()); 785397536cabe12a9936659870dd220c869789424bacdalton const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer); 786e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer); 78717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 78817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth bool success = false; 78955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrMipLevel mipLevel; 790c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth mipLevel.fPixels = transferBuffer; 79155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume mipLevel.fRowBytes = rowBytes; 79255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume SkSTArray<1, GrMipLevel> texels; 79355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume texels.push_back(mipLevel); 794e7d7f90b59b15a291c113b449f5c6ac57f8d1aacjcgregorio success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_UploadType, 79555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume left, top, width, height, config, texels); 796900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return success; 79717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth} 79817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 799f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon// For GL_[UN]PACK_ALIGNMENT. 800f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomonstatic inline GrGLint config_alignment(GrPixelConfig config) { 801f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon SkASSERT(!GrPixelConfigIsCompressed(config)); 802f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon switch (config) { 803f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kAlpha_8_GrPixelConfig: 804986563bcff26300ea4317b4dd84917d5240bb723Brian Osman case kGray_8_GrPixelConfig: 805f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon return 1; 806f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kRGB_565_GrPixelConfig: 807f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kRGBA_4444_GrPixelConfig: 808f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kAlpha_half_GrPixelConfig: 809f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kRGBA_half_GrPixelConfig: 810f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon return 2; 811f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kRGBA_8888_GrPixelConfig: 812f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kBGRA_8888_GrPixelConfig: 813f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kSRGBA_8888_GrPixelConfig: 814a6359365887048ef055196de75591311d7a015f0brianosman case kSBGRA_8888_GrPixelConfig: 815bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon case kRGBA_8888_sint_GrPixelConfig: 816f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon case kRGBA_float_GrPixelConfig: 8176aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton case kRG_float_GrPixelConfig: 818f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon return 4; 8196aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton case kUnknown_GrPixelConfig: 8206aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton case kETC1_GrPixelConfig: 821f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon return 0; 822f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon } 8236aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton SkFAIL("Invalid pixel config"); 8246aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton return 0; 825f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon} 826f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon 827b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomonstatic inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, 828b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon const GrGLInterface* interface) { 829f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { 830d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org return GR_GL_GET_ERROR(interface); 831d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org } else { 832d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org return CHECK_ALLOC_ERROR(interface); 833d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org } 834d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org} 835d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org 83655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume/** 83755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * Creates storage space for the texture and fills it with texels. 83855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * 83955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param desc The surface descriptor for the texture being created. 84055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param interface The GL interface in use. 841790d5132620d86813380d3df251e80dd2b41a409cblume * @param caps The capabilities of the GL device. 84281a8485997162a6f2bef84b1130033b1222c722cbrianosman * @param internalFormat The data format used for the internal storage of the texture. May be sized. 84381a8485997162a6f2bef84b1130033b1222c722cbrianosman * @param internalFormatForTexStorage The data format used for the TexStorage API. Must be sized. 84455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param externalFormat The data format used for the external storage of the texture. 84555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param externalType The type of the data used for the external storage of the texture. 84655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param texels The texel data of the texture being created. 84755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param baseWidth The width of the texture's base mipmap level 84855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param baseHeight The height of the texture's base mipmap level 84955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param succeeded Set to true if allocating and populating the texture completed 85055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * without error. 85155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume */ 852e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomonstatic bool allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc, 85355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const GrGLInterface& interface, 854790d5132620d86813380d3df251e80dd2b41a409cblume const GrGLCaps& caps, 85555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLenum target, 85655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLenum internalFormat, 85781a8485997162a6f2bef84b1130033b1222c722cbrianosman GrGLenum internalFormatForTexStorage, 85855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLenum externalFormat, 85955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLenum externalType, 86055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels, 861e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon int baseWidth, int baseHeight) { 86255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume CLEAR_ERROR_BEFORE_ALLOC(&interface); 863790d5132620d86813380d3df251e80dd2b41a409cblume 864790d5132620d86813380d3df251e80dd2b41a409cblume bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig); 865790d5132620d86813380d3df251e80dd2b41a409cblume // We can only use TexStorage if we know we will not later change the storage requirements. 866790d5132620d86813380d3df251e80dd2b41a409cblume // This means if we may later want to add mipmaps, we cannot use TexStorage. 867790d5132620d86813380d3df251e80dd2b41a409cblume // Right now, we cannot know if we will later add mipmaps or not. 868790d5132620d86813380d3df251e80dd2b41a409cblume // The only time we can use TexStorage is when we already have the 869bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon // mipmaps or are using a format incompatible with MIP maps. 870bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon useTexStorage &= texels.count() > 1 || GrPixelConfigIsSint(desc.fConfig); 871790d5132620d86813380d3df251e80dd2b41a409cblume 872790d5132620d86813380d3df251e80dd2b41a409cblume if (useTexStorage) { 873790d5132620d86813380d3df251e80dd2b41a409cblume // We never resize or change formats of textures. 87455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GL_ALLOC_CALL(&interface, 875790d5132620d86813380d3df251e80dd2b41a409cblume TexStorage2D(target, 876bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon SkTMax(texels.count(), 1), 87781a8485997162a6f2bef84b1130033b1222c722cbrianosman internalFormatForTexStorage, 878790d5132620d86813380d3df251e80dd2b41a409cblume desc.fWidth, desc.fHeight)); 87955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLenum error = check_alloc_error(desc, &interface); 88055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (error != GR_GL_NO_ERROR) { 881e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon return false; 882790d5132620d86813380d3df251e80dd2b41a409cblume } else { 883790d5132620d86813380d3df251e80dd2b41a409cblume for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) { 884790d5132620d86813380d3df251e80dd2b41a409cblume const void* currentMipData = texels[currentMipLevel].fPixels; 885790d5132620d86813380d3df251e80dd2b41a409cblume if (currentMipData == nullptr) { 886790d5132620d86813380d3df251e80dd2b41a409cblume continue; 887790d5132620d86813380d3df251e80dd2b41a409cblume } 888790d5132620d86813380d3df251e80dd2b41a409cblume int twoToTheMipLevel = 1 << currentMipLevel; 889790d5132620d86813380d3df251e80dd2b41a409cblume int currentWidth = SkTMax(1, desc.fWidth / twoToTheMipLevel); 890790d5132620d86813380d3df251e80dd2b41a409cblume int currentHeight = SkTMax(1, desc.fHeight / twoToTheMipLevel); 891790d5132620d86813380d3df251e80dd2b41a409cblume 892790d5132620d86813380d3df251e80dd2b41a409cblume GR_GL_CALL(&interface, 893790d5132620d86813380d3df251e80dd2b41a409cblume TexSubImage2D(target, 894790d5132620d86813380d3df251e80dd2b41a409cblume currentMipLevel, 895790d5132620d86813380d3df251e80dd2b41a409cblume 0, // left 896790d5132620d86813380d3df251e80dd2b41a409cblume 0, // top 897790d5132620d86813380d3df251e80dd2b41a409cblume currentWidth, 898790d5132620d86813380d3df251e80dd2b41a409cblume currentHeight, 899790d5132620d86813380d3df251e80dd2b41a409cblume externalFormat, externalType, 900790d5132620d86813380d3df251e80dd2b41a409cblume currentMipData)); 901790d5132620d86813380d3df251e80dd2b41a409cblume } 902e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon return true; 903790d5132620d86813380d3df251e80dd2b41a409cblume } 904790d5132620d86813380d3df251e80dd2b41a409cblume } else { 905e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon if (texels.empty()) { 906790d5132620d86813380d3df251e80dd2b41a409cblume GL_ALLOC_CALL(&interface, 907790d5132620d86813380d3df251e80dd2b41a409cblume TexImage2D(target, 908e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon 0, 909790d5132620d86813380d3df251e80dd2b41a409cblume internalFormat, 910e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon baseWidth, 911e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon baseHeight, 912790d5132620d86813380d3df251e80dd2b41a409cblume 0, // border 913790d5132620d86813380d3df251e80dd2b41a409cblume externalFormat, externalType, 914e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon nullptr)); 915790d5132620d86813380d3df251e80dd2b41a409cblume GrGLenum error = check_alloc_error(desc, &interface); 916790d5132620d86813380d3df251e80dd2b41a409cblume if (error != GR_GL_NO_ERROR) { 917e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon return false; 918e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon } 919e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon } else { 920e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) { 921e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon int twoToTheMipLevel = 1 << currentMipLevel; 922e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); 923e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); 924e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon const void* currentMipData = texels[currentMipLevel].fPixels; 925e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon // Even if curremtMipData is nullptr, continue to call TexImage2D. 926e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon // This will allocate texture memory which we can later populate. 927e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon GL_ALLOC_CALL(&interface, 928e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon TexImage2D(target, 929e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon currentMipLevel, 930e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon internalFormat, 931e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon currentWidth, 932e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon currentHeight, 933e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon 0, // border 934e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon externalFormat, externalType, 935e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon currentMipData)); 936e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon GrGLenum error = check_alloc_error(desc, &interface); 937e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon if (error != GR_GL_NO_ERROR) { 938e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon return false; 939e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon } 940790d5132620d86813380d3df251e80dd2b41a409cblume } 94155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 94255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 943e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon return true; 94455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume} 94555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 94655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume/** 94755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * Creates storage space for the texture and fills it with texels. 94855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * 94955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param desc The surface descriptor for the texture being created. 95055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param interface The GL interface in use. 951790d5132620d86813380d3df251e80dd2b41a409cblume * @param caps The capabilities of the GL device. 95255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param internalFormat The data format used for the internal storage of the texture. 95355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param texels The texel data of the texture being created. 95455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume */ 95555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblumestatic bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc, 95655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const GrGLInterface& interface, 957790d5132620d86813380d3df251e80dd2b41a409cblume const GrGLCaps& caps, 95855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLenum target, GrGLenum internalFormat, 95955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels, 96055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int baseWidth, int baseHeight) { 96155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume CLEAR_ERROR_BEFORE_ALLOC(&interface); 96255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 963790d5132620d86813380d3df251e80dd2b41a409cblume bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig); 964790d5132620d86813380d3df251e80dd2b41a409cblume // We can only use TexStorage if we know we will not later change the storage requirements. 965790d5132620d86813380d3df251e80dd2b41a409cblume // This means if we may later want to add mipmaps, we cannot use TexStorage. 966790d5132620d86813380d3df251e80dd2b41a409cblume // Right now, we cannot know if we will later add mipmaps or not. 967790d5132620d86813380d3df251e80dd2b41a409cblume // The only time we can use TexStorage is when we already have the 968790d5132620d86813380d3df251e80dd2b41a409cblume // mipmaps. 969790d5132620d86813380d3df251e80dd2b41a409cblume useTexStorage &= texels.count() > 1; 97055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 971790d5132620d86813380d3df251e80dd2b41a409cblume if (useTexStorage) { 972790d5132620d86813380d3df251e80dd2b41a409cblume // We never resize or change formats of textures. 97355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GL_ALLOC_CALL(&interface, 974790d5132620d86813380d3df251e80dd2b41a409cblume TexStorage2D(target, 975790d5132620d86813380d3df251e80dd2b41a409cblume texels.count(), 976790d5132620d86813380d3df251e80dd2b41a409cblume internalFormat, 977790d5132620d86813380d3df251e80dd2b41a409cblume baseWidth, baseHeight)); 97855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLenum error = check_alloc_error(desc, &interface); 97955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (error != GR_GL_NO_ERROR) { 98055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume return false; 981790d5132620d86813380d3df251e80dd2b41a409cblume } else { 982790d5132620d86813380d3df251e80dd2b41a409cblume for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) { 983790d5132620d86813380d3df251e80dd2b41a409cblume const void* currentMipData = texels[currentMipLevel].fPixels; 984790d5132620d86813380d3df251e80dd2b41a409cblume if (currentMipData == nullptr) { 985790d5132620d86813380d3df251e80dd2b41a409cblume continue; 986790d5132620d86813380d3df251e80dd2b41a409cblume } 987790d5132620d86813380d3df251e80dd2b41a409cblume 988790d5132620d86813380d3df251e80dd2b41a409cblume int twoToTheMipLevel = 1 << currentMipLevel; 989790d5132620d86813380d3df251e80dd2b41a409cblume int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); 990790d5132620d86813380d3df251e80dd2b41a409cblume int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); 991790d5132620d86813380d3df251e80dd2b41a409cblume 992790d5132620d86813380d3df251e80dd2b41a409cblume // Make sure that the width and height that we pass to OpenGL 993790d5132620d86813380d3df251e80dd2b41a409cblume // is a multiple of the block size. 994790d5132620d86813380d3df251e80dd2b41a409cblume size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentWidth, 995790d5132620d86813380d3df251e80dd2b41a409cblume currentHeight); 996790d5132620d86813380d3df251e80dd2b41a409cblume GR_GL_CALL(&interface, CompressedTexSubImage2D(target, 997790d5132620d86813380d3df251e80dd2b41a409cblume currentMipLevel, 998790d5132620d86813380d3df251e80dd2b41a409cblume 0, // left 999790d5132620d86813380d3df251e80dd2b41a409cblume 0, // top 1000790d5132620d86813380d3df251e80dd2b41a409cblume currentWidth, 1001790d5132620d86813380d3df251e80dd2b41a409cblume currentHeight, 1002790d5132620d86813380d3df251e80dd2b41a409cblume internalFormat, 1003790d5132620d86813380d3df251e80dd2b41a409cblume SkToInt(dataSize), 1004790d5132620d86813380d3df251e80dd2b41a409cblume currentMipData)); 1005790d5132620d86813380d3df251e80dd2b41a409cblume } 1006790d5132620d86813380d3df251e80dd2b41a409cblume } 1007790d5132620d86813380d3df251e80dd2b41a409cblume } else { 1008790d5132620d86813380d3df251e80dd2b41a409cblume for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) { 1009790d5132620d86813380d3df251e80dd2b41a409cblume int twoToTheMipLevel = 1 << currentMipLevel; 1010790d5132620d86813380d3df251e80dd2b41a409cblume int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); 1011790d5132620d86813380d3df251e80dd2b41a409cblume int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); 1012790d5132620d86813380d3df251e80dd2b41a409cblume 1013790d5132620d86813380d3df251e80dd2b41a409cblume // Make sure that the width and height that we pass to OpenGL 1014790d5132620d86813380d3df251e80dd2b41a409cblume // is a multiple of the block size. 1015790d5132620d86813380d3df251e80dd2b41a409cblume size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth, baseHeight); 1016790d5132620d86813380d3df251e80dd2b41a409cblume 1017790d5132620d86813380d3df251e80dd2b41a409cblume GL_ALLOC_CALL(&interface, 1018790d5132620d86813380d3df251e80dd2b41a409cblume CompressedTexImage2D(target, 1019790d5132620d86813380d3df251e80dd2b41a409cblume currentMipLevel, 1020790d5132620d86813380d3df251e80dd2b41a409cblume internalFormat, 1021790d5132620d86813380d3df251e80dd2b41a409cblume currentWidth, 1022790d5132620d86813380d3df251e80dd2b41a409cblume currentHeight, 1023790d5132620d86813380d3df251e80dd2b41a409cblume 0, // border 1024790d5132620d86813380d3df251e80dd2b41a409cblume SkToInt(dataSize), 1025790d5132620d86813380d3df251e80dd2b41a409cblume texels[currentMipLevel].fPixels)); 1026790d5132620d86813380d3df251e80dd2b41a409cblume 1027790d5132620d86813380d3df251e80dd2b41a409cblume GrGLenum error = check_alloc_error(desc, &interface); 1028790d5132620d86813380d3df251e80dd2b41a409cblume if (error != GR_GL_NO_ERROR) { 1029790d5132620d86813380d3df251e80dd2b41a409cblume return false; 1030790d5132620d86813380d3df251e80dd2b41a409cblume } 103155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 103255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 103355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 103455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume return true; 103555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume} 103655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 103755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume/** 103855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * After a texture is created, any state which was altered during its creation 103955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * needs to be restored. 104055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * 104155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param interface The GL interface to use. 104255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param caps The capabilities of the GL device. 104355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param restoreGLRowLength Should the row length unpacking be restored? 104455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param glFlipY Did GL flip the texture vertically? 104555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume */ 104655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblumestatic void restore_pixelstore_state(const GrGLInterface& interface, const GrGLCaps& caps, 104755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume bool restoreGLRowLength, bool glFlipY) { 104855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (restoreGLRowLength) { 104955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume SkASSERT(caps.unpackRowLengthSupport()); 105055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 105155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 105255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (glFlipY) { 105355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 105455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 105555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume} 105655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 1057861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonbool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, 1058e7d7f90b59b15a291c113b449f5c6ac57f8d1aacjcgregorio GrGLenum target, 105917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth UploadType uploadType, 10606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, int width, int height, 10616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig dataConfig, 106255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels) { 10636e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org // If we're uploading compressed data then we should be using uploadCompressedTexData 10646e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 10656e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org 10665b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); 10675b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon 106855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // texels is const. 106955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // But we may need to flip the texture vertically to prepare it. 107055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // Rather than flip in place and alter the incoming data, 107155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // we allocate a new buffer to flip into. 107255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // This means we need to make a non-const shallow copy of texels. 107355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume SkTArray<GrMipLevel> texelsShallowCopy(texels); 107455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 107555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0; 107655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentMipLevel--) { 1077e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon SkASSERT(texelsShallowCopy[currentMipLevel].fPixels || kTransfer_UploadType == uploadType); 107855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 107955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 108055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const GrGLInterface* interface = this->glInterface(); 108155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const GrGLCaps& caps = this->glCaps(); 108255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 1083a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com size_t bpp = GrBytesPerPixel(dataConfig); 108455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 108555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (width == 0 || height == 0) { 1086136f55b61752e01b0f140f4b7fbc8db00205a06bbsalomon@google.com return false; 108771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 10886f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 108955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { 109055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int twoToTheMipLevel = 1 << currentMipLevel; 109155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentWidth = SkTMax(1, width / twoToTheMipLevel); 109255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentHeight = SkTMax(1, height / twoToTheMipLevel); 109355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 109455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (currentHeight > SK_MaxS32 || 109555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentWidth > SK_MaxS32) { 109655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume return false; 109755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 109855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 109955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume ¤tWidth, 110055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume ¤tHeight, 110155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume &texelsShallowCopy[currentMipLevel].fPixels, 110255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume &texelsShallowCopy[currentMipLevel].fRowBytes)) { 110355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume return false; 110455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 110555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (currentWidth < 0 || currentHeight < 0) { 110655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume return false; 110755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 110855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 110971f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com 11105b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon // Internal format comes from the texture desc. 111176148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum internalFormat; 11125b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon // External format and type come from the upload data. 111376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalFormat; 111476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalType; 111576148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon if (!this->glCaps().getTexImageFormats(desc.fConfig, dataConfig, &internalFormat, 111676148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon &externalFormat, &externalType)) { 111776148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon return false; 111876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon } 111981a8485997162a6f2bef84b1130033b1222c722cbrianosman // TexStorage requires a sized format, and internalFormat may or may not be 112081a8485997162a6f2bef84b1130033b1222c722cbrianosman GrGLenum internalFormatForTexStorage = this->glCaps().configSizedInternalFormat(desc.fConfig); 112181a8485997162a6f2bef84b1130033b1222c722cbrianosman 112271f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com /* 11235b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon * Check whether to allocate a temporary buffer for flipping y or 11246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com * because our srcData has extra bytes past each row. If so, we need 11256f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com * to trim those off here, since GL ES may not let us specify 11266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com * GL_UNPACK_ROW_LENGTH. 112771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com */ 11286f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com bool restoreGLRowLength = false; 11298ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com bool swFlipY = false; 11308ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com bool glFlipY = false; 113155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 1132e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty()) { 113355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (caps.unpackFlipYSupport()) { 113455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume glFlipY = true; 113555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } else { 113655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume swFlipY = true; 113771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 113855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 113955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 114055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // in case we need a temporary, trimmed copy of the src pixels 114155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume SkAutoSMalloc<128 * 128> tempStorage; 114255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 114355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // find the combined size of all the mip levels and the relative offset of 114455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // each into the collective buffer 114555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume size_t combined_buffer_size = 0; 114655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume SkTArray<size_t> individual_mip_offsets(texelsShallowCopy.count()); 114755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { 114855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int twoToTheMipLevel = 1 << currentMipLevel; 114955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentWidth = SkTMax(1, width / twoToTheMipLevel); 115055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentHeight = SkTMax(1, height / twoToTheMipLevel); 115155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const size_t trimmedSize = currentWidth * bpp * currentHeight; 115255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume individual_mip_offsets.push_back(combined_buffer_size); 115355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume combined_buffer_size += trimmedSize; 115455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 115555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume char* buffer = (char*)tempStorage.reset(combined_buffer_size); 115655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 115755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { 115855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int twoToTheMipLevel = 1 << currentMipLevel; 115955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentWidth = SkTMax(1, width / twoToTheMipLevel); 116055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentHeight = SkTMax(1, height / twoToTheMipLevel); 116155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const size_t trimRowBytes = currentWidth * bpp; 116255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 116355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume /* 116455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * check whether to allocate a temporary buffer for flipping y or 116555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * because our srcData has extra bytes past each row. If so, we need 116655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * to trim those off here, since GL ES may not let us specify 116755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * GL_UNPACK_ROW_LENGTH. 116855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume */ 116955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume restoreGLRowLength = false; 117055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 117155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes; 1172154349b6fff27a19533ae528d43a5b52e4e11d3dericrk 1173154349b6fff27a19533ae528d43a5b52e4e11d3dericrk // TODO: This optimization should be enabled with or without mips. 1174154349b6fff27a19533ae528d43a5b52e4e11d3dericrk // For use with mips, we must set GR_GL_UNPACK_ROW_LENGTH once per 1175154349b6fff27a19533ae528d43a5b52e4e11d3dericrk // mip level, before calling glTexImage2D. 1176154349b6fff27a19533ae528d43a5b52e4e11d3dericrk const bool usesMips = texelsShallowCopy.count() > 1; 1177154349b6fff27a19533ae528d43a5b52e4e11d3dericrk if (caps.unpackRowLengthSupport() && !swFlipY && !usesMips) { 1178b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com // can't use this for flipping, only non-neg values allowed. :( 1179b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com if (rowBytes != trimRowBytes) { 1180b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); 118155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); 1182b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com restoreGLRowLength = true; 118371f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 118417aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth } else if (kTransfer_UploadType != uploadType) { 1185b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com if (trimRowBytes != rowBytes || swFlipY) { 1186b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com // copy data into our new storage, skipping the trailing bytes 118755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels; 118855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (swFlipY && currentHeight >= 1) { 118955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume src += (currentHeight - 1) * rowBytes; 1190b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com } 119155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume char* dst = buffer + individual_mip_offsets[currentMipLevel]; 119255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume for (int y = 0; y < currentHeight; y++) { 1193b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com memcpy(dst, src, trimRowBytes); 1194b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com if (swFlipY) { 1195b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com src -= rowBytes; 1196b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com } else { 1197b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com src += rowBytes; 1198b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com } 1199b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com dst += trimRowBytes; 120071f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 1201b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com // now point data to our copied version 120255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume texelsShallowCopy[currentMipLevel].fPixels = buffer + 120355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume individual_mip_offsets[currentMipLevel]; 120455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes; 120571f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 120617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth } else { 120717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth return false; 120871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 1209e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon } 1210e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon 1211e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon if (!texelsShallowCopy.empty()) { 1212b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com if (glFlipY) { 121355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); 1214b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com } 121555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, 121655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume config_alignment(desc.fConfig))); 121771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 121855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 1219b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com bool succeeded = true; 122055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (kNewTexture_UploadType == uploadType && 122155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 0 == left && 0 == top && 12227e68ab73186ab02a6030d3959e7372f983f85af5bsalomon desc.fWidth == width && desc.fHeight == height) { 1223e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon succeeded = allocate_and_populate_uncompressed_texture(desc, *interface, caps, target, 122481a8485997162a6f2bef84b1130033b1222c722cbrianosman internalFormat, 122581a8485997162a6f2bef84b1130033b1222c722cbrianosman internalFormatForTexStorage, 122681a8485997162a6f2bef84b1130033b1222c722cbrianosman externalFormat, externalType, 122781a8485997162a6f2bef84b1130033b1222c722cbrianosman texelsShallowCopy, width, height); 122871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } else { 12298ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com if (swFlipY || glFlipY) { 12306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com top = desc.fHeight - (top + height); 123171f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com } 123255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); 123355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentMipLevel++) { 123455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int twoToTheMipLevel = 1 << currentMipLevel; 123555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentWidth = SkTMax(1, width / twoToTheMipLevel); 123655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentHeight = SkTMax(1, height / twoToTheMipLevel); 12376f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 123855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GL_CALL(TexSubImage2D(target, 123955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentMipLevel, 124055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume left, top, 124155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentWidth, 124255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentHeight, 124355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume externalFormat, externalType, 124455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume texelsShallowCopy[currentMipLevel].fPixels)); 124555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 12468ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com } 124755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 124855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY); 124955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 1250b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com return succeeded; 125171f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com} 125271f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com 1253145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// TODO: This function is using a lot of wonky semantics like, if width == -1 1254e4b231428e8c14cbc82d20cfb12eb08fc45f8df6piotaixr// then set width = desc.fWdith ... blah. A better way to do it might be to 1255145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// create a CompressedTexData struct that takes a desc/ptr and figures out 1256145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// the proper upload semantics. Then users can construct this function how they 1257145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// see fit if they want to go against the "standard" way to do it. 1258861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonbool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, 125910528f1d5838ae1cac015024c4e8731484f888d1bsalomon GrGLenum target, 126055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels, 126117aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth UploadType uploadType, 1262145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski int left, int top, int width, int height) { 12632555ee2e9940d00d0cc54772a934e7215d055ba2bsalomon SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); 12649c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 12659c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // No support for software flip y, yet... 12669c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); 12679c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 126855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const GrGLInterface* interface = this->glInterface(); 126955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const GrGLCaps& caps = this->glCaps(); 127055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 1271145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski if (-1 == width) { 1272145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski width = desc.fWidth; 1273145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski } 1274145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#ifdef SK_DEBUG 1275145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski else { 1276145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski SkASSERT(width <= desc.fWidth); 1277145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski } 1278145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#endif 1279145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski 1280145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski if (-1 == height) { 1281145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski height = desc.fHeight; 1282145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski } 1283145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#ifdef SK_DEBUG 1284145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski else { 1285145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski SkASSERT(height <= desc.fHeight); 1286145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski } 1287145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#endif 1288145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski 128976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon // We only need the internal format for compressed 2D textures. 129076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum internalFormat; 129155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (!caps.getCompressedTexImageFormats(desc.fConfig, &internalFormat)) { 129276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon return false; 129376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon } 12949c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 129517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth if (kNewTexture_UploadType == uploadType) { 1296790d5132620d86813380d3df251e80dd2b41a409cblume return allocate_and_populate_compressed_texture(desc, *interface, caps, target, 1297790d5132620d86813380d3df251e80dd2b41a409cblume internalFormat, texels, width, height); 1298145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski } else { 129955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) { 1300e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon SkASSERT(texels[currentMipLevel].fPixels || kTransfer_UploadType == uploadType); 130155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 130255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int twoToTheMipLevel = 1 << currentMipLevel; 130355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentWidth = SkTMax(1, width / twoToTheMipLevel); 130455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume int currentHeight = SkTMax(1, height / twoToTheMipLevel); 130555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 130655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // Make sure that the width and height that we pass to OpenGL 130755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // is a multiple of the block size. 130855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentWidth, 130955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentHeight); 131055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GL_CALL(CompressedTexSubImage2D(target, 131155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentMipLevel, 131255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume left, top, 131355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentWidth, 131455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume currentHeight, 131555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume internalFormat, 131655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume SkToInt(dataSize), 131755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume texels[currentMipLevel].fPixels)); 131855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 1319145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski } 13209c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 1321d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon return true; 13229c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski} 13239c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 1324424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomonstatic bool renderbuffer_storage_msaa(const GrGLContext& ctx, 1325040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org int sampleCount, 1326040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org GrGLenum format, 1327040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org int width, int height) { 13286177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); 1329b1854a85095f9924947bc00e665da47b0c0bdfb9commit-bot@chromium.org SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType()); 1330b1854a85095f9924947bc00e665da47b0c0bdfb9commit-bot@chromium.org switch (ctx.caps()->msFBOType()) { 133100731b42bcd89b98ef01b5aad3bbe51cb7018c9cBrian Salomon case GrGLCaps::kEXT_MSFBOType: 133200731b42bcd89b98ef01b5aad3bbe51cb7018c9cBrian Salomon case GrGLCaps::kStandard_MSFBOType: 1333dded69693dd3779f081326cde24c3954505b129dvbuzinov case GrGLCaps::kMixedSamples_MSFBOType: 1334040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org GL_ALLOC_CALL(ctx.interface(), 1335040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org RenderbufferStorageMultisample(GR_GL_RENDERBUFFER, 1336040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org sampleCount, 1337040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org format, 1338040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org width, height)); 1339040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org break; 1340040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org case GrGLCaps::kES_Apple_MSFBOType: 1341040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org GL_ALLOC_CALL(ctx.interface(), 1342040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org RenderbufferStorageMultisampleES2APPLE(GR_GL_RENDERBUFFER, 1343040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org sampleCount, 1344040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org format, 1345040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org width, height)); 1346040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org break; 1347040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org case GrGLCaps::kES_EXT_MsToTexture_MSFBOType: 1348040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org case GrGLCaps::kES_IMG_MsToTexture_MSFBOType: 1349040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org GL_ALLOC_CALL(ctx.interface(), 1350040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org RenderbufferStorageMultisampleES2EXT(GR_GL_RENDERBUFFER, 1351040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org sampleCount, 1352040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org format, 1353040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org width, height)); 1354040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org break; 1355040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org case GrGLCaps::kNone_MSFBOType: 135688cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Shouldn't be here if we don't support multisampled renderbuffers."); 1357040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org break; 1358c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com } 13599251d4e9c6191aa26680911ed938dafdaebf5f61Brian Salomon return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface())); 1360c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com} 1361c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com 1362b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdanielbool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, 1363091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon const GrGLTextureInfo& texInfo, 1364b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GrGLRenderTarget::IDDesc* idDesc) { 1365b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon idDesc->fMSColorRenderbufferID = 0; 1366d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel idDesc->fRTFBOID = 0; 13672e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen idDesc->fRTFBOOwnership = GrBackendObjectOwnership::kOwned; 1368d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel idDesc->fTexFBOID = 0; 136976948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) == 137076948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips this->caps()->usesMixedSamples()); 1371f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton idDesc->fIsMixedSampled = desc.fSampleCnt > 0 && this->caps()->usesMixedSamples(); 137281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 137381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com GrGLenum status; 137481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 1375a11e5fce33f8d6f38c3324d639ca76ddf12598babsalomon GrGLenum colorRenderbufferFormat = 0; // suppress warning 1376ab15d618ae8c75360d414e206ae30a6845d185c4bsalomon@google.com 1377b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) { 1378347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com goto FAILED; 1379347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com } 1380347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com 1381d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(GenFramebuffers(1, &idDesc->fTexFBOID)); 1382d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (!idDesc->fTexFBOID) { 138381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com goto FAILED; 138481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 1385fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1386f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com // If we are using multisampling we will create two FBOS. We render to one and then resolve to 1387f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com // the texture bound to the other. The exception is the IMG multisample extension. With this 1388f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com // extension the texture is multisampled when rendered to and then auto-resolves it when it is 1389f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com // rendered from. 1390b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { 1391d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID)); 1392b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); 1393d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (!idDesc->fRTFBOID || 1394a11e5fce33f8d6f38c3324d639ca76ddf12598babsalomon !idDesc->fMSColorRenderbufferID) { 139581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com goto FAILED; 139681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 139776148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon if (!this->glCaps().getRenderbufferFormat(desc.fConfig, &colorRenderbufferFormat)) { 139876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon return false; 139976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon } 140081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } else { 1401d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel idDesc->fRTFBOID = idDesc->fTexFBOID; 140281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 140381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 1404d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // below here we may bind the FBO 1405294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 1406d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (idDesc->fRTFBOID != idDesc->fTexFBOID) { 1407b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon SkASSERT(desc.fSampleCnt > 0); 1408b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbufferID)); 1409424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon if (!renderbuffer_storage_msaa(*fGLContext, 1410b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon desc.fSampleCnt, 1411a11e5fce33f8d6f38c3324d639ca76ddf12598babsalomon colorRenderbufferFormat, 1412b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon desc.fWidth, desc.fHeight)) { 141381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com goto FAILED; 141481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 1415d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fStats.incRenderTargetBinds(); 1416d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); 1417d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 141810528f1d5838ae1cac015024c4e8731484f888d1bsalomon GR_GL_COLOR_ATTACHMENT0, 141910528f1d5838ae1cac015024c4e8731484f888d1bsalomon GR_GL_RENDERBUFFER, 142010528f1d5838ae1cac015024c4e8731484f888d1bsalomon idDesc->fMSColorRenderbufferID)); 1421b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || 1422b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { 14234bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 14244bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 14254bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com goto FAILED; 14264bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com } 1427424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); 142881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 142981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 1430d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fStats.incRenderTargetBinds(); 1431d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID)); 143281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 1433b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { 1434d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, 1435f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com GR_GL_COLOR_ATTACHMENT0, 1436091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon texInfo.fTarget, 1437091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon texInfo.fID, 0, desc.fSampleCnt)); 1438f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com } else { 1439d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, 1440f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com GR_GL_COLOR_ATTACHMENT0, 1441091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon texInfo.fTarget, 1442091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon texInfo.fID, 0)); 1443f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com } 1444b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || 1445b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { 1446d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 14474bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 14484bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com goto FAILED; 14494bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com } 1450424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); 145181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 145281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 145381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com return true; 145481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 145581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.comFAILED: 1456b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon if (idDesc->fMSColorRenderbufferID) { 1457b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); 145881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 1459d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (idDesc->fRTFBOID != idDesc->fTexFBOID) { 1460d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(DeleteFramebuffers(1, &idDesc->fRTFBOID)); 146181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 1462d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (idDesc->fTexFBOID) { 1463d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(DeleteFramebuffers(1, &idDesc->fTexFBOID)); 146481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 146581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com return false; 146681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com} 146781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 14683f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com// good to set a break-point here to know when createTexture fails 14693f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.comstatic GrTexture* return_null_texture() { 1470330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com// SkDEBUGFAIL("null texture"); 147196fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 14723f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com} 14733f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com 1474515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#if 0 && defined(SK_DEBUG) 14753f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.comstatic size_t as_size_t(int x) { 14763f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com return x; 14773f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com} 14783f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com#endif 14793f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com 14802e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunenstatic GrGLTexture::IDDesc generate_gl_texture(const GrGLInterface* interface) { 148155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLTexture::IDDesc idDesc; 148255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume idDesc.fInfo.fID = 0; 148355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, GenTextures(1, &idDesc.fInfo.fID)); 14842e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen idDesc.fOwnership = GrBackendObjectOwnership::kOwned; 148555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // When we create the texture, we only 148655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // create GL_TEXTURE_2D at the moment. 148755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // External clients can do something different. 148855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; 148955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume return idDesc; 149055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume} 149155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 149255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblumestatic void set_initial_texture_params(const GrGLInterface* interface, 149355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const GrGLTextureInfo& info, 149455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GrGLTexture::TexParams* initialTexParams) { 149555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 149655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // drivers have a bug where an FBO won't be complete if it includes a 149755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // texture that is not mipmap complete (considering the filter in use). 149855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume // we only set a subset here so invalidate first 149955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->invalidate(); 150055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fMinFilter = GR_GL_NEAREST; 150155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fMagFilter = GR_GL_NEAREST; 150255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fWrapS = GR_GL_CLAMP_TO_EDGE; 150355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fWrapT = GR_GL_CLAMP_TO_EDGE; 150455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, TexParameteri(info.fTarget, 150555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_TEXTURE_MAG_FILTER, 150655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fMagFilter)); 150755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, TexParameteri(info.fTarget, 150855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_TEXTURE_MIN_FILTER, 150955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fMinFilter)); 151055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, TexParameteri(info.fTarget, 151155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_TEXTURE_WRAP_S, 151255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fWrapS)); 151355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_CALL(interface, TexParameteri(info.fTarget, 151455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume GR_GL_TEXTURE_WRAP_T, 151555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume initialTexParams->fWrapT)); 151655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume} 151755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 1518b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdanielGrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, 15192e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SkBudgeted budgeted, 152055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels) { 15218a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com // We fail if the MSAA was requested and is not available. 15228a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) { 152338406c82b913350e55fa04af8c1941cd9b4aff52tfarina //SkDebugf("MSAA RT requested but not supported on this platform."); 15248a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com return return_null_texture(); 15258a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com } 152671f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com 1527f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 1528ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 1529b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon GrGLTexture::IDDesc idDesc; 15302e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen idDesc.fOwnership = GrBackendObjectOwnership::kOwned; 15310a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrGLTexture::TexParams initialTexParams; 153255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (!this->createTextureImpl(desc, &idDesc.fInfo, renderTarget, &initialTexParams, texels)) { 1533b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com return return_null_texture(); 15346f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1535ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 1536d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips bool wasMipMapDataProvided = false; 1537d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips if (texels.count() > 1) { 1538d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips wasMipMapDataProvided = true; 1539d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips } 1540d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 154181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com GrGLTexture* tex; 1542ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (renderTarget) { 1543ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com // unbind the texture from the texture unit before binding it to the frame buffer 1544091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0)); 15455236cf480daf82b2f36e42795abdbbc915533a59bsalomon GrGLRenderTarget::IDDesc rtIDDesc; 1546ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com 15472e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen if (!this->createRenderTargetObjects(desc, idDesc.fInfo, &rtIDDesc)) { 1548091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); 154981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com return return_null_texture(); 1550a16d6506bde44f8528e681a49c412a1e87b74482bsalomon@google.com } 1551d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips tex = new GrGLTextureRenderTarget(this, budgeted, desc, idDesc, rtIDDesc, 1552d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips wasMipMapDataProvided); 155381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } else { 15542e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen tex = new GrGLTexture(this, budgeted, desc, idDesc, wasMipMapDataProvided); 155581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 15560a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 155781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com#ifdef TRACE_TEXTURE_CREATION 155838406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", 1559c4459f6a3381b033dc7871701a647820d8f6bec4brianosman idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig); 156081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com#endif 156181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com return tex; 156281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com} 1563ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 1564b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdanielGrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, 15652e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SkBudgeted budgeted, 156655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels) { 15679c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Make sure that we're not flipping Y. 1568b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdaniel if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 15699c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return return_null_texture(); 15709c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 15719c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 15722e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface()); 1573091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon if (!idDesc.fInfo.fID) { 15749c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return return_null_texture(); 15759c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 15769c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 15779c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski this->setScratchTextureUnit(); 1578091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); 15799c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 15809c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski GrGLTexture::TexParams initialTexParams; 158155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume set_initial_texture_params(this->glInterface(), idDesc.fInfo, &initialTexParams); 158255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 158355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (!this->uploadCompressedTexData(desc, idDesc.fInfo.fTarget, texels)) { 1584091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); 15859c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return return_null_texture(); 15869c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 15879c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 15889c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski GrGLTexture* tex; 15892e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen tex = new GrGLTexture(this, budgeted, desc, idDesc); 15909c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 15919c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#ifdef TRACE_TEXTURE_CREATION 159238406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", 1593c4459f6a3381b033dc7871701a647820d8f6bec4brianosman idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig); 15949c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#endif 15959c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return tex; 15969c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski} 15979c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 159881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.comnamespace { 1599f7fa806d84abf1cba47bfa8679e875a75d76599ebsalomon@google.com 16008dc7c3a839b38b73af34cc2674a06f49eb1ce527egdanielconst GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; 1601f7fa806d84abf1cba47bfa8679e875a75d76599ebsalomon@google.com 16020b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.comvoid inline get_stencil_rb_sizes(const GrGLInterface* gl, 16038dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel GrGLStencilAttachment::Format* format) { 16046ba0b0f9ad566e57e641c57e1f0f4876f2197010sugoi@google.com 160581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com // we shouldn't ever know one size and not the other 1606f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT((kUnknownBitCount == format->fStencilBits) == 160781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com (kUnknownBitCount == format->fTotalBits)); 160881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com if (kUnknownBitCount == format->fStencilBits) { 16090b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 161081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com GR_GL_RENDERBUFFER_STENCIL_SIZE, 161181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com (GrGLint*)&format->fStencilBits); 161281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com if (format->fPacked) { 16130b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, 161481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com GR_GL_RENDERBUFFER_DEPTH_SIZE, 161581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com (GrGLint*)&format->fTotalBits); 161681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com format->fTotalBits += format->fStencilBits; 161781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } else { 161881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com format->fTotalBits = format->fStencilBits; 161981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 162081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com } 162181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com} 162281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com} 16234043ae20615c79298f190865665beeb6b86e14d0bsalomon@google.com 1624ff1d547c72b7c70af7bddfba01d4646b2389db7aegdanielint GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) { 1625100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon static const int kSize = 16; 1626926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon SkASSERT(this->caps()->isConfigRenderable(config, false)); 1627304473749db1ee877addb3ddf090d2e36ede2c2absalomon if (!this->glCaps().hasStencilFormatBeenDeterminedForConfig(config)) { 1628304473749db1ee877addb3ddf090d2e36ede2c2absalomon // Default to unsupported, set this if we find a stencil format that works. 1629304473749db1ee877addb3ddf090d2e36ede2c2absalomon int firstWorkingStencilFormatIndex = -1; 1630ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // Create color texture 1631546eb5c57aebee47172f9d2a3eae6b49945dba08kkinnunen GrGLuint colorID = 0; 1632ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(GenTextures(1, &colorID)); 1633ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel this->setScratchTextureUnit(); 1634ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(BindTexture(GR_GL_TEXTURE_2D, colorID)); 1635ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1636ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_TEXTURE_MAG_FILTER, 1637ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_NEAREST)); 1638ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1639ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_TEXTURE_MIN_FILTER, 1640ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_NEAREST)); 1641ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1642ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_TEXTURE_WRAP_S, 1643ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_CLAMP_TO_EDGE)); 1644ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1645ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_TEXTURE_WRAP_T, 1646ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_CLAMP_TO_EDGE)); 1647ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 164876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum internalFormat; 164976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalFormat; 165076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalType; 165176148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat, 165276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon &externalType)) { 165376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon return false; 165476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon } 16554f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1656ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, 1657926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon 0, 165876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon internalFormat, 1659100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon kSize, 1660100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon kSize, 1661ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 0, 166276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon externalFormat, 166376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon externalType, 1664ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel NULL)); 1665304473749db1ee877addb3ddf090d2e36ede2c2absalomon if (GR_GL_NO_ERROR != CHECK_ALLOC_ERROR(this->glInterface())) { 1666ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(DeleteTextures(1, &colorID)); 1667304473749db1ee877addb3ddf090d2e36ede2c2absalomon return -1; 1668fe6765293f9f16707a8f246f44c006c6e9abd33ebsalomon@google.com } 166973165bd417d6cd4b4513df54b58e23e33f151a3frobertphillips 1670ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // unbind the texture from the texture unit before binding it to the frame buffer 1671ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); 1672ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 1673ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // Create Framebuffer 1674546eb5c57aebee47172f9d2a3eae6b49945dba08kkinnunen GrGLuint fb = 0; 1675ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(GenFramebuffers(1, &fb)); 1676ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fb)); 1677294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 1678ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, 1679ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_COLOR_ATTACHMENT0, 1680ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_TEXTURE_2D, 1681ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel colorID, 1682ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 0)); 1683304473749db1ee877addb3ddf090d2e36ede2c2absalomon GrGLuint sbRBID = 0; 1684304473749db1ee877addb3ddf090d2e36ede2c2absalomon GL_CALL(GenRenderbuffers(1, &sbRBID)); 1685ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 1686ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // look over formats till I find a compatible one 1687ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel int stencilFmtCnt = this->glCaps().stencilFormats().count(); 1688304473749db1ee877addb3ddf090d2e36ede2c2absalomon if (sbRBID) { 1689ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbRBID)); 1690304473749db1ee877addb3ddf090d2e36ede2c2absalomon for (int i = 0; i < stencilFmtCnt && sbRBID; ++i) { 1691304473749db1ee877addb3ddf090d2e36ede2c2absalomon const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[i]; 1692304473749db1ee877addb3ddf090d2e36ede2c2absalomon CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1693304473749db1ee877addb3ddf090d2e36ede2c2absalomon GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER, 1694304473749db1ee877addb3ddf090d2e36ede2c2absalomon sFmt.fInternalFormat, 1695304473749db1ee877addb3ddf090d2e36ede2c2absalomon kSize, kSize)); 1696304473749db1ee877addb3ddf090d2e36ede2c2absalomon if (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface())) { 1697d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1698304473749db1ee877addb3ddf090d2e36ede2c2absalomon GR_GL_STENCIL_ATTACHMENT, 1699ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_RENDERBUFFER, sbRBID)); 1700304473749db1ee877addb3ddf090d2e36ede2c2absalomon if (sFmt.fPacked) { 1701304473749db1ee877addb3ddf090d2e36ede2c2absalomon GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1702304473749db1ee877addb3ddf090d2e36ede2c2absalomon GR_GL_DEPTH_ATTACHMENT, 1703304473749db1ee877addb3ddf090d2e36ede2c2absalomon GR_GL_RENDERBUFFER, sbRBID)); 1704304473749db1ee877addb3ddf090d2e36ede2c2absalomon } else { 1705304473749db1ee877addb3ddf090d2e36ede2c2absalomon GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1706304473749db1ee877addb3ddf090d2e36ede2c2absalomon GR_GL_DEPTH_ATTACHMENT, 1707304473749db1ee877addb3ddf090d2e36ede2c2absalomon GR_GL_RENDERBUFFER, 0)); 1708304473749db1ee877addb3ddf090d2e36ede2c2absalomon } 1709304473749db1ee877addb3ddf090d2e36ede2c2absalomon GrGLenum status; 1710304473749db1ee877addb3ddf090d2e36ede2c2absalomon GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1711304473749db1ee877addb3ddf090d2e36ede2c2absalomon if (status == GR_GL_FRAMEBUFFER_COMPLETE) { 1712304473749db1ee877addb3ddf090d2e36ede2c2absalomon firstWorkingStencilFormatIndex = i; 1713304473749db1ee877addb3ddf090d2e36ede2c2absalomon break; 1714304473749db1ee877addb3ddf090d2e36ede2c2absalomon } 1715ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1716ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_STENCIL_ATTACHMENT, 1717ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_RENDERBUFFER, 0)); 1718ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel if (sFmt.fPacked) { 1719ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1720ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_DEPTH_ATTACHMENT, 1721ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GR_GL_RENDERBUFFER, 0)); 1722ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel } 1723ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel } 172412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon } 1725304473749db1ee877addb3ddf090d2e36ede2c2absalomon GL_CALL(DeleteRenderbuffers(1, &sbRBID)); 1726ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 1727ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(DeleteTextures(1, &colorID)); 1728ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); 1729ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(DeleteFramebuffers(1, &fb)); 1730304473749db1ee877addb3ddf090d2e36ede2c2absalomon fGLContext->caps()->setStencilFormatIndexForConfig(config, firstWorkingStencilFormatIndex); 1731ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 1732304473749db1ee877addb3ddf090d2e36ede2c2absalomon return this->glCaps().getStencilFormatIndexForConfig(config); 1733ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel} 1734ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 17359a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchenbool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, 173655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume bool renderTarget, GrGLTexture::TexParams* initialTexParams, 173755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume const SkTArray<GrMipLevel>& texels) { 17389a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen info->fID = 0; 17399a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen info->fTarget = GR_GL_TEXTURE_2D; 17409a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen GL_CALL(GenTextures(1, &(info->fID))); 17419a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen 17429a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen if (!info->fID) { 17439a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen return false; 17449a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen } 17459a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen 17469a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen this->setScratchTextureUnit(); 17479a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen GL_CALL(BindTexture(info->fTarget, info->fID)); 17489a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen 17499a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen if (renderTarget && this->glCaps().textureUsageSupport()) { 17509a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen // provides a hint about how this texture will be used 17519a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen GL_CALL(TexParameteri(info->fTarget, 17529a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen GR_GL_TEXTURE_USAGE, 17539a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen GR_GL_FRAMEBUFFER_ATTACHMENT)); 17549a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen } 17559a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen 175655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (info) { 175755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume set_initial_texture_params(this->glInterface(), *info, initialTexParams); 175855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 17599a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen if (!this->uploadTexData(desc, info->fTarget, kNewTexture_UploadType, 0, 0, 17609a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen desc.fWidth, desc.fHeight, 176155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume desc.fConfig, texels)) { 17629a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen GL_CALL(DeleteTextures(1, &(info->fID))); 17639a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen return false; 17649a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen } 17659a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen return true; 17669a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen} 17679a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen 1768ec00d94199fad7723b5987b86c1abef8ddafe2d8egdanielGrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 1769ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel int width, 1770ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel int height) { 1771ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel SkASSERT(width >= rt->width()); 1772ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel SkASSERT(height >= rt->height()); 1773ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 1774ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel int samples = rt->numStencilSamples(); 1775ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GrGLStencilAttachment::IDDesc sbDesc; 1776ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 1777ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel int sIdx = this->getCompatibleStencilIndex(rt->config()); 177862a627be6a7e3fdb4fe1c67de0c371a276c761f6bsalomon if (sIdx < 0) { 1779ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel return nullptr; 1780ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel } 1781ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel 1782ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel if (!sbDesc.fRenderbufferID) { 1783ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID)); 1784ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel } 1785ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel if (!sbDesc.fRenderbufferID) { 1786ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel return nullptr; 1787ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel } 1788ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); 1789ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx]; 1790ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1791ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // we do this "if" so that we don't call the multisample 1792ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // version on a GL that doesn't have an MSAA extension. 1793ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel if (samples > 0) { 1794ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel SkAssertResult(renderbuffer_storage_msaa(*fGLContext, 1795ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel samples, 1796ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel sFmt.fInternalFormat, 1797ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel width, height)); 1798ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel } else { 1799ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER, 1800ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel sFmt.fInternalFormat, 1801ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel width, height)); 1802ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel SkASSERT(GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface())); 1803ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel } 1804ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel fStats.incStencilAttachmentCreates(); 1805ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // After sized formats we attempt an unsized format and take 1806ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel // whatever sizes GL gives us. In that case we query for the size. 1807ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel GrGLStencilAttachment::Format format = sFmt; 1808ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel get_stencil_rb_sizes(this->glInterface(), &format); 1809ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel GrGLStencilAttachment* stencil = new GrGLStencilAttachment(this, 1810ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel sbDesc, 1811ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel width, 1812ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel height, 1813ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel samples, 1814ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel format); 1815ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel return stencil; 1816ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 1817ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 181871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 181971f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com 182073063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth// GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer 182173063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth// objects are implemented as client-side-arrays on tile-deferred architectures. 182273063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth#define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW 182373063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth 1824e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonGrBuffer* GrGLGpu::onCreateBuffer(size_t size, GrBufferType intendedType, 18251bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton GrAccessPattern accessPattern, const void* data) { 18261bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton return GrGLBuffer::Create(this, size, intendedType, accessPattern, data); 182773063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth} 182873063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth 1829e0d362929d6569e8737d80dead791c640390e819csmartdaltonInstancedRendering* GrGLGpu::onCreateInstancedRendering() { 1830e0d362929d6569e8737d80dead791c640390e819csmartdalton return new GLInstancedRendering(this); 1831e0d362929d6569e8737d80dead791c640390e819csmartdalton} 1832e0d362929d6569e8737d80dead791c640390e819csmartdalton 18333e79124a69d4806f0a1a776090bff718e1b90970bsalomonvoid GrGLGpu::flushScissor(const GrScissorState& scissorState, 183477b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt const GrGLIRect& rtViewport, 183577b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt GrSurfaceOrigin rtOrigin) { 1836e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips if (scissorState.enabled()) { 1837a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com GrGLIRect scissor; 1838b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon scissor.setRelativeTo(rtViewport, 1839e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips scissorState.rect().fLeft, 1840e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips scissorState.rect().fTop, 1841e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips scissorState.rect().width(), 1842e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips scissorState.rect().height(), 1843b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon rtOrigin); 1844a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com // if the scissor fully contains the viewport then we fall through and 1845a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com // disable the scissor test. 1846b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon if (!scissor.contains(rtViewport)) { 1847a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com if (fHWScissorSettings.fRect != scissor) { 1848a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com scissor.pushToGLScissor(this->glInterface()); 1849a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com fHWScissorSettings.fRect = scissor; 1850a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com } 1851a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com if (kYes_TriState != fHWScissorSettings.fEnabled) { 1852a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com GL_CALL(Enable(GR_GL_SCISSOR_TEST)); 1853a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com fHWScissorSettings.fEnabled = kYes_TriState; 1854a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com } 1855a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com return; 1856a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com } 1857730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com } 185877b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt 185977b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt // See fall through note above 186077b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt this->disableScissor(); 186177b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt} 186277b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt 1863bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdaltonvoid GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState, 1864bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton const GrGLRenderTarget* rt) { 186532ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#ifndef USE_NSIGHT 1866bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton typedef GrWindowRectsState::Mode Mode; 1867bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton SkASSERT(!windowState.enabled() || rt->renderFBOID()); // Window rects can't be used on-screen. 1868bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton SkASSERT(windowState.numWindows() <= this->caps()->maxWindowRectangles()); 186928341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton 187028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton if (!this->caps()->maxWindowRectangles() || 1871bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton fHWWindowRectsState.knownEqualTo(rt->origin(), rt->getViewport(), windowState)) { 187228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton return; 187328341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton } 187428341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton 18757535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton // This is purely a workaround for a spurious warning generated by gcc. Otherwise the above 18767535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton // assert would be sufficient. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=5912 1877bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton int numWindows = SkTMin(windowState.numWindows(), int(GrWindowRectangles::kMaxWindows)); 1878bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton SkASSERT(windowState.numWindows() == numWindows); 18797535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton 188028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton GrGLIRect glwindows[GrWindowRectangles::kMaxWindows]; 1881bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton const SkIRect* skwindows = windowState.windows().data(); 18827535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton for (int i = 0; i < numWindows; ++i) { 18839a7677273a3f270e6137d396e972c83c036a47a7Brian Salomon glwindows[i].setRelativeTo(rt->getViewport(), skwindows[i], rt->origin()); 188428341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton } 188528341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton 1886bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE; 18877535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton GL_CALL(WindowRectangles(glmode, numWindows, glwindows->asInts())); 188828341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton 1889bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton fHWWindowRectsState.set(rt->origin(), rt->getViewport(), windowState); 189032ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#endif 189128341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton} 189228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton 189328341fad8438b294ed7311edbc68d8cb34a990abcsmartdaltonvoid GrGLGpu::disableWindowRectangles() { 189432ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#ifndef USE_NSIGHT 1895bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton if (!this->caps()->maxWindowRectangles() || fHWWindowRectsState.knownDisabled()) { 189628341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton return; 189728341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton } 189828341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton GL_CALL(WindowRectangles(GR_GL_EXCLUSIVE, 0, nullptr)); 1899bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton fHWWindowRectsState.setDisabled(); 190032ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#endif 190128341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton} 190228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton 190328ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholasvoid GrGLGpu::flushMinSampleShading(float minSampleShading) { 190428ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas if (fHWMinSampleShading != minSampleShading) { 190528ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas if (minSampleShading > 0.0) { 190628ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas GL_CALL(Enable(GR_GL_SAMPLE_SHADING)); 190728ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas GL_CALL(MinSampleShading(minSampleShading)); 190828ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas } 190928ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas else { 191028ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas GL_CALL(Disable(GR_GL_SAMPLE_SHADING)); 191128ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas } 191228ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas fHWMinSampleShading = minSampleShading; 191328ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas } 191428ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas} 191528ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas 19162eda5b3a65f54105ae3776160373eed5500c515fbsalomonbool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc, 19172eda5b3a65f54105ae3776160373eed5500c515fbsalomon bool willDrawPoints) { 1918144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc, willDrawPoints)); 191933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!program) { 192033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrCapsDebugf(this->caps(), "Failed to create program!\n"); 192133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 192233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 192333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 192433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman program->generateMipmaps(primProc, pipeline); 192533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 1926080e673b10ac607305f140ddb245e140ccde40c6egdaniel GrXferProcessor::BlendInfo blendInfo; 19270e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel pipeline.getXferProcessor().getBlendInfo(&blendInfo); 1928080e673b10ac607305f140ddb245e140ccde40c6egdaniel 1929080e673b10ac607305f140ddb245e140ccde40c6egdaniel this->flushColorWrite(blendInfo.fWriteColor); 19308dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel this->flushDrawFace(pipeline.getDrawFace()); 193128ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas this->flushMinSampleShading(primProc.getSampleShading()); 1932bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 19336df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLuint programID = program->programID(); 19341f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon if (fHWProgramID != programID) { 19351f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon GL_CALL(UseProgram(programID)); 19361f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon fHWProgramID = programID; 19371f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon } 1938bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1939d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (blendInfo.fWriteColor) { 19407f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon // Swizzle the blend to match what the shader will output. 19411edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon const GrSwizzle& swizzle = this->caps()->shaderCaps()->configOutputSwizzle( 19420e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel pipeline.getRenderTarget()->config()); 19437f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon this->flushBlend(blendInfo, swizzle); 1944d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel } 1945bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 194674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton program->setData(primProc, pipeline); 1947bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1948898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget()); 1949c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton GrStencilSettings stencil; 1950c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton if (pipeline.isStencilEnabled()) { 1951c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton // TODO: attach stencil and create settings during render target flush. 1952c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton SkASSERT(glRT->renderTargetPriv().getStencilAttachment()); 1953c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), 1954c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton glRT->renderTargetPriv().numStencilBits()); 1955c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton } 1956c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton this->flushStencil(stencil); 19578dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin()); 1958bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT); 1959dabc91bc0f42a9484b6025ddc68fa958455fb53ccsmartdalton this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled()); 1960bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1961bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon // This must come after textures are flushed because a texture may need 1962d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // to be msaa-resolved (which will modify bound FBO state). 196364d094d7756534a9b9b0997aab225d9ceba098b6brianosman this->flushRenderTarget(glRT, nullptr, pipeline.getDisableOutputConversionToSRGB()); 1964bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1965bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon return true; 1966bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon} 1967bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1968873ad0e0b4d67bdc7bad025018f597450e7004c6joshualittvoid GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, 19690e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrNonInstancedMesh& mesh, 1970bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon size_t* indexOffsetInBytes) { 1971485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton const GrBuffer* vbuf = mesh.vertexBuffer(); 1972bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon SkASSERT(vbuf); 1973bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon SkASSERT(!vbuf->isMapped()); 1974bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1975e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GrGLAttribArrayState* attribState; 19760e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (mesh.isIndexed()) { 1977bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon SkASSERT(indexOffsetInBytes); 1978bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1979bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon *indexOffsetInBytes = 0; 1980485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton const GrBuffer* ibuf = mesh.indexBuffer(); 1981bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon SkASSERT(ibuf); 1982bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon SkASSERT(!ibuf->isMapped()); 1983bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon *indexOffsetInBytes += ibuf->baseOffset(); 1984e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton attribState = fHWVertexArrayState.bindInternalVertexArray(this, ibuf); 1985e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } else { 1986e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton attribState = fHWVertexArrayState.bindInternalVertexArray(this); 1987bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon } 1988bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1989873ad0e0b4d67bdc7bad025018f597450e7004c6joshualitt int vaCount = primProc.numAttribs(); 199071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt if (vaCount > 0) { 1991bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1992873ad0e0b4d67bdc7bad025018f597450e7004c6joshualitt GrGLsizei stride = static_cast<GrGLsizei>(primProc.getVertexStride()); 1993bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 19940e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel size_t vertexOffsetInBytes = stride * mesh.startVertex(); 1995bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1996bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon vertexOffsetInBytes += vbuf->baseOffset(); 1997bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 1998bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon uint32_t usedAttribArraysMask = 0; 1999bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon size_t offset = 0; 2000bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 2001bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { 2002873ad0e0b4d67bdc7bad025018f597450e7004c6joshualitt const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(attribIndex); 2003bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon usedAttribArraysMask |= (1 << attribIndex); 200471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt GrVertexAttribType attribType = attrib.fType; 2005bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon attribState->set(this, 2006bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon attribIndex, 2007e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vbuf, 2008793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton attribType, 2009bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon stride, 2010bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + offset)); 201171c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt offset += attrib.fOffset; 2012bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon } 2013bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon attribState->disableUnusedArrays(this, usedAttribArraysMask); 2014bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon } 2015bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon} 2016bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon 2017485a12003ab48b54965d6f7172f3183358919d8ecsmartdaltonGrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrBuffer* buffer) { 201893316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt this->handleDirtyContext(); 2019e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 2020e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton // Index buffer state is tied to the vertex array. 2021e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (kIndex_GrBufferType == type) { 2022e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton this->bindVertexArray(0); 202393316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt } 202493316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt 2025e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton SkASSERT(type >= 0 && type <= kLast_GrBufferType); 2026e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton auto& bufferState = fHWBufferState[type]; 2027e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 20288abb370aca280516f4861c6c942ec453aad018farobertphillips if (buffer->uniqueID() != bufferState.fBoundBufferUniqueID) { 2029485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton if (buffer->isCPUBacked()) { 2030485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton if (!bufferState.fBufferZeroKnownBound) { 2031485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton GL_CALL(BindBuffer(bufferState.fGLTarget, 0)); 2032485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton } 2033485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton } else { 2034485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(buffer); 2035485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton GL_CALL(BindBuffer(bufferState.fGLTarget, glBuffer->bufferID())); 2036e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 2037485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton bufferState.fBufferZeroKnownBound = buffer->isCPUBacked(); 20388abb370aca280516f4861c6c942ec453aad018farobertphillips bufferState.fBoundBufferUniqueID = buffer->uniqueID(); 203993316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt } 2040e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 2041e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return bufferState.fGLTarget; 204293316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt} 204393316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt 204474b8d323323c8533e3e5cc7719e0bd127aacd829cdaltonvoid GrGLGpu::notifyBufferReleased(const GrGLBuffer* buffer) { 204574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (buffer->hasAttachedToTexture()) { 204674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton // Detach this buffer from any textures to ensure the underlying memory is freed. 2047294870ff119b89fc902773643b054f14e5d1f554Robert Phillips GrGpuResource::UniqueID uniqueID = buffer->uniqueID(); 204874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton for (int i = fHWMaxUsedBufferTextureUnit; i >= 0; --i) { 204974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton auto& buffTex = fHWBufferTextures[i]; 205074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (uniqueID != buffTex.fAttachedBufferUniqueID) { 205174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton continue; 205274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 205374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (i == fHWMaxUsedBufferTextureUnit) { 205474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton --fHWMaxUsedBufferTextureUnit; 205574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 205674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 205774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->setTextureUnit(i); 205874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (!buffTex.fKnownBound) { 205974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton SkASSERT(buffTex.fTextureID); 206074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID)); 206174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton buffTex.fKnownBound = true; 206274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 206374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER, 206474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->glCaps().configSizedInternalFormat(buffTex.fTexelConfig), 0)); 206574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 206674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 206774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton} 206874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 2069861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::disableScissor() { 2070a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com if (kNo_TriState != fHWScissorSettings.fEnabled) { 2071730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com GL_CALL(Disable(GR_GL_SCISSOR_TEST)); 2072a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com fHWScissorSettings.fEnabled = kNo_TriState; 2073a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com return; 2074ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 2075ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2076ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 207729df76096fd30941086324902a82656df2d8becdcsmartdaltonvoid GrGLGpu::clear(const GrFixedClip& clip, GrColor color, GrRenderTarget* target) { 20789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel this->handleDirtyContext(); 20799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 20800ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com // parent class should never let us get here with no RT 208149f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(target); 2082b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); 20830ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com 208429df76096fd30941086324902a82656df2d8becdcsmartdalton this->flushRenderTarget(glRT, clip.scissorEnabled() ? &clip.scissorRect() : nullptr); 208529df76096fd30941086324902a82656df2d8becdcsmartdalton this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin()); 2086bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton this->flushWindowRectangles(clip.windowRectsState(), glRT); 208774b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com 208874b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com GrGLfloat r, g, b, a; 208974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com static const GrGLfloat scale255 = 1.f / 255.f; 209074b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com a = GrColorUnpackA(color) * scale255; 209174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com GrGLfloat scaleRGB = scale255; 209274b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com r = GrColorUnpackR(color) * scaleRGB; 209374b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com g = GrColorUnpackG(color) * scaleRGB; 209474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com b = GrColorUnpackB(color) * scaleRGB; 209574b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com 209674b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 2097978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com fHWWriteToColor = kYes_TriState; 209874b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com GL_CALL(ClearColor(r, g, b, a)); 20990b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); 2100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2102861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::clearStencil(GrRenderTarget* target) { 210396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == target) { 21047d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com return; 21057d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com } 2106b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); 2107d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); 21088295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 210977b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt this->disableScissor(); 211028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton this->disableWindowRectangles(); 2111730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com 21120b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(StencilMask(0xffffffff)); 21130b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(ClearStencil(0)); 21140b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 2115457b8a3b49d5cf946674bbaa959a86bd137bf582bsalomon@google.com fHWStencilSettings.invalidate(); 2116ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2117ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 211829df76096fd30941086324902a82656df2d8becdcsmartdaltonvoid GrGLGpu::clearStencilClip(const GrFixedClip& clip, 211929df76096fd30941086324902a82656df2d8becdcsmartdalton bool insideStencilMask, 212029df76096fd30941086324902a82656df2d8becdcsmartdalton GrRenderTarget* target) { 212149f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(target); 21229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel this->handleDirtyContext(); 212381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com 21248dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment(); 212581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com // this should only be called internally when we know we have a 212681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com // stencil buffer. 21276bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon SkASSERT(sb); 21286bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon GrGLint stencilBitCount = sb->bits(); 2129ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com#if 0 2130f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(stencilBitCount > 0); 21310f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); 21325aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com#else 21335aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com // we could just clear the clip bit but when we go through 213481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com // ANGLE a partial stencil mask will cause clears to be 2135f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips // turned into draws. Our contract on GrOpList says that 21365aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com // changing the clip between stencil passes may or may not 21375aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com // zero the client's clip bits. So we just clear the whole thing. 21380f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com static const GrGLint clipStencilMask = ~0; 21395aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com#endif 2140ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com GrGLint value; 214129df76096fd30941086324902a82656df2d8becdcsmartdalton if (insideStencilMask) { 2142ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com value = (1 << (stencilBitCount - 1)); 2143ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com } else { 2144ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com value = 0; 2145ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com } 2146b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); 2147d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); 2148a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com 214929df76096fd30941086324902a82656df2d8becdcsmartdalton this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin()); 2150bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton this->flushWindowRectangles(clip.windowRectsState(), glRT); 2151a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com 2152cf6285b89b8820641ffb6871d4b3275bfe783f51caryclark@google.com GL_CALL(StencilMask((uint32_t) clipStencilMask)); 2153ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com GL_CALL(ClearStencil(value)); 21540b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 2155457b8a3b49d5cf946674bbaa959a86bd137bf582bsalomon@google.com fHWStencilSettings.invalidate(); 2156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 215871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomonstatic bool read_pixels_pays_for_y_flip(GrSurfaceOrigin origin, const GrGLCaps& caps, 2159398260262f8508687614ec496a23b8152bcdc967bsalomon int width, int height, GrPixelConfig config, 2160398260262f8508687614ec496a23b8152bcdc967bsalomon size_t rowBytes) { 216171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon // If the surface is already TopLeft, we don't need to flip. 216271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (kTopLeft_GrSurfaceOrigin == origin) { 21633cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org return false; 21643cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org } 21653cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org 2166494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon // If the read is really small or smaller than the min texture size, don't force a draw. 2167100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon static const int kMinSize = 32; 2168100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon if (width < kMinSize || height < kMinSize) { 2169494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon return false; 2170494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon } 2171494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon 217256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // if GL can do the flip then we'll never pay for it. 2173398260262f8508687614ec496a23b8152bcdc967bsalomon if (caps.packFlipYSupport()) { 217456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com return false; 217556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 217656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 217756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // If we have to do memcpy to handle non-trim rowBytes then we 21787107fa789a5999e3f8f7cf7c9c4208c2c443d2afbsalomon@google.com // get the flip for free. Otherwise it costs. 2179398260262f8508687614ec496a23b8152bcdc967bsalomon // Note that we're assuming that 0 rowBytes has already been handled and that the width has been 2180398260262f8508687614ec496a23b8152bcdc967bsalomon // clipped. 2181398260262f8508687614ec496a23b8152bcdc967bsalomon return caps.packRowLengthSupport() || GrBytesPerPixel(config) * width == rowBytes; 2182398260262f8508687614ec496a23b8152bcdc967bsalomon} 2183398260262f8508687614ec496a23b8152bcdc967bsalomon 21841aa202935ff698f1f35c5435455073fd9f1d08debsalomonbool GrGLGpu::readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig) { 2185625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon#ifdef SK_BUILD_FOR_MAC 2186625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon // Chromium may ask us to read back from locked IOSurfaces. Calling the command buffer's 2187625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon // glGetIntegerv() with GL_IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE causes the command buffer 2188625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon // to make a call to check the framebuffer status which can hang the driver. So in Mac Chromium 2189625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon // we always use a temporary surface to test for read pixels support. 2190625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon // https://www.crbug.com/662802 2191625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon if (this->glContext().driver() == kChromium_GrGLDriver) { 2192625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon return this->readPixelsSupported(target->config(), readConfig); 2193625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon } 2194625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon#endif 21951aa202935ff698f1f35c5435455073fd9f1d08debsalomon auto bindRenderTarget = [this, target]() -> bool { 21961aa202935ff698f1f35c5435455073fd9f1d08debsalomon this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target), &SkIRect::EmptyIRect()); 21971aa202935ff698f1f35c5435455073fd9f1d08debsalomon return true; 21981aa202935ff698f1f35c5435455073fd9f1d08debsalomon }; 21992c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon auto unbindRenderTarget = []{}; 22001aa202935ff698f1f35c5435455073fd9f1d08debsalomon auto getIntegerv = [this](GrGLenum query, GrGLint* value) { 22011aa202935ff698f1f35c5435455073fd9f1d08debsalomon GR_GL_GetIntegerv(this->glInterface(), query, value); 22021aa202935ff698f1f35c5435455073fd9f1d08debsalomon }; 22031aa202935ff698f1f35c5435455073fd9f1d08debsalomon GrPixelConfig rtConfig = target->config(); 22042c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget, 22052c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon unbindRenderTarget); 22061aa202935ff698f1f35c5435455073fd9f1d08debsalomon} 22071aa202935ff698f1f35c5435455073fd9f1d08debsalomon 22081aa202935ff698f1f35c5435455073fd9f1d08debsalomonbool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConfig) { 22092c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon sk_sp<GrTexture> temp; 22102c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon auto bindRenderTarget = [this, rtConfig, &temp]() -> bool { 22111aa202935ff698f1f35c5435455073fd9f1d08debsalomon GrTextureDesc desc; 22121aa202935ff698f1f35c5435455073fd9f1d08debsalomon desc.fConfig = rtConfig; 22131aa202935ff698f1f35c5435455073fd9f1d08debsalomon desc.fWidth = desc.fHeight = 16; 22142c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon if (this->glCaps().isConfigRenderable(rtConfig, false)) { 22152c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon desc.fFlags = kRenderTarget_GrSurfaceFlag; 22162c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon temp.reset(this->createTexture(desc, SkBudgeted::kNo)); 22172c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon if (!temp) { 22182c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon return false; 22192c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon } 22202c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(temp->asRenderTarget()); 22212c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon this->flushRenderTarget(glrt, &SkIRect::EmptyIRect()); 22222c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon return true; 22232c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon } else if (this->glCaps().canConfigBeFBOColorAttachment(rtConfig)) { 22242c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon temp.reset(this->createTexture(desc, SkBudgeted::kNo)); 22252c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon if (!temp) { 22262c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon return false; 22272c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon } 22282c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon GrGLIRect vp; 22292c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon this->bindSurfaceFBOForPixelOps(temp.get(), GR_GL_FRAMEBUFFER, &vp, kDst_TempFBOTarget); 2230294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 22312c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon return true; 22321aa202935ff698f1f35c5435455073fd9f1d08debsalomon } 22332c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon return false; 22342c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon }; 22352c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon auto unbindRenderTarget = [this, &temp]() { 22362c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, temp.get()); 22371aa202935ff698f1f35c5435455073fd9f1d08debsalomon }; 22381aa202935ff698f1f35c5435455073fd9f1d08debsalomon auto getIntegerv = [this](GrGLenum query, GrGLint* value) { 22391aa202935ff698f1f35c5435455073fd9f1d08debsalomon GR_GL_GetIntegerv(this->glInterface(), query, value); 22401aa202935ff698f1f35c5435455073fd9f1d08debsalomon }; 22412c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget, 22422c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon unbindRenderTarget); 22431aa202935ff698f1f35c5435455073fd9f1d08debsalomon} 22441aa202935ff698f1f35c5435455073fd9f1d08debsalomon 22451aa202935ff698f1f35c5435455073fd9f1d08debsalomonbool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig) { 22461aa202935ff698f1f35c5435455073fd9f1d08debsalomon if (GrRenderTarget* rt = surfaceForConfig->asRenderTarget()) { 22471aa202935ff698f1f35c5435455073fd9f1d08debsalomon return this->readPixelsSupported(rt, readConfig); 22481aa202935ff698f1f35c5435455073fd9f1d08debsalomon } else { 22491aa202935ff698f1f35c5435455073fd9f1d08debsalomon GrPixelConfig config = surfaceForConfig->config(); 22501aa202935ff698f1f35c5435455073fd9f1d08debsalomon return this->readPixelsSupported(config, readConfig); 22511aa202935ff698f1f35c5435455073fd9f1d08debsalomon } 22521aa202935ff698f1f35c5435455073fd9f1d08debsalomon} 22531aa202935ff698f1f35c5435455073fd9f1d08debsalomon 2254e9573317d35d08254412eb407211f3607f8f74fbbsalomonstatic bool requires_srgb_conversion(GrPixelConfig a, GrPixelConfig b) { 2255e9573317d35d08254412eb407211f3607f8f74fbbsalomon if (GrPixelConfigIsSRGB(a)) { 2256e9573317d35d08254412eb407211f3607f8f74fbbsalomon return !GrPixelConfigIsSRGB(b) && !GrPixelConfigIsAlphaOnly(b); 2257e9573317d35d08254412eb407211f3607f8f74fbbsalomon } else if (GrPixelConfigIsSRGB(b)) { 2258e9573317d35d08254412eb407211f3607f8f74fbbsalomon return !GrPixelConfigIsSRGB(a) && !GrPixelConfigIsAlphaOnly(a); 2259e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2260e9573317d35d08254412eb407211f3607f8f74fbbsalomon return false; 2261e9573317d35d08254412eb407211f3607f8f74fbbsalomon} 2262e9573317d35d08254412eb407211f3607f8f74fbbsalomon 2263f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomonbool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 2264f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon GrPixelConfig readConfig, DrawPreference* drawPreference, 2265f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon ReadPixelTempDrawInfo* tempDrawInfo) { 2266e9573317d35d08254412eb407211f3607f8f74fbbsalomon GrPixelConfig srcConfig = srcSurface->config(); 2267398260262f8508687614ec496a23b8152bcdc967bsalomon 2268e9573317d35d08254412eb407211f3607f8f74fbbsalomon // These settings we will always want if a temp draw is performed. 2269398260262f8508687614ec496a23b8152bcdc967bsalomon tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag; 2270398260262f8508687614ec496a23b8152bcdc967bsalomon tempDrawInfo->fTempSurfaceDesc.fWidth = width; 2271398260262f8508687614ec496a23b8152bcdc967bsalomon tempDrawInfo->fTempSurfaceDesc.fHeight = height; 2272398260262f8508687614ec496a23b8152bcdc967bsalomon tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 2273398260262f8508687614ec496a23b8152bcdc967bsalomon tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. 2274b117ff194ff888ef9107a4797aad053b0d76be30bsalomon tempDrawInfo->fTempSurfaceFit = this->glCaps().partialFBOReadIsSlow() ? SkBackingFit::kExact 2275b117ff194ff888ef9107a4797aad053b0d76be30bsalomon : SkBackingFit::kApprox; 2276e9573317d35d08254412eb407211f3607f8f74fbbsalomon // For now assume no swizzling, we may change that below. 2277e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); 2278e9573317d35d08254412eb407211f3607f8f74fbbsalomon 2279e9573317d35d08254412eb407211f3607f8f74fbbsalomon // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read 2280e9573317d35d08254412eb407211f3607f8f74fbbsalomon // from will be srcConfig and we will read readConfig pixels from it. 2281e9573317d35d08254412eb407211f3607f8f74fbbsalomon // Not that if we require a draw and return a non-renderable format for the temp surface the 2282e9573317d35d08254412eb407211f3607f8f74fbbsalomon // base class will fail for us. 2283e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 2284e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempDrawInfo->fReadConfig = readConfig; 2285e9573317d35d08254412eb407211f3607f8f74fbbsalomon 2286e9573317d35d08254412eb407211f3607f8f74fbbsalomon if (requires_srgb_conversion(srcConfig, readConfig)) { 2287e9573317d35d08254412eb407211f3607f8f74fbbsalomon if (!this->readPixelsSupported(readConfig, readConfig)) { 2288e9573317d35d08254412eb407211f3607f8f74fbbsalomon return false; 2289e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2290e9573317d35d08254412eb407211f3607f8f74fbbsalomon // Draw to do srgb to linear conversion or vice versa. 2291e9573317d35d08254412eb407211f3607f8f74fbbsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2292e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; 2293e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempDrawInfo->fReadConfig = readConfig; 2294e9573317d35d08254412eb407211f3607f8f74fbbsalomon return true; 2295e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2296e9573317d35d08254412eb407211f3607f8f74fbbsalomon 22971aa202935ff698f1f35c5435455073fd9f1d08debsalomon if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig && 22981aa202935ff698f1f35c5435455073fd9f1d08debsalomon this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelConfig)) { 2299398260262f8508687614ec496a23b8152bcdc967bsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig; 23006c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 23016c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig; 2302b411b3b87dcdfc124f7eec5581d510a5282a8563bsalomon ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2303b4ecabd5a2c359f66a20207ffb02a77e624560c4ericrk } else if (this->glCaps().rgbaToBgraReadbackConversionsAreSlow() && 2304398260262f8508687614ec496a23b8152bcdc967bsalomon GrBytesPerPixel(readConfig) == 4 && 23051aa202935ff698f1f35c5435455073fd9f1d08debsalomon GrPixelConfigSwapRAndB(readConfig) == srcConfig && 23061aa202935ff698f1f35c5435455073fd9f1d08debsalomon this->readPixelsSupported(srcSurface, srcConfig)) { 23076c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa. 2308398260262f8508687614ec496a23b8152bcdc967bsalomon // Better to do a draw with a R/B swap and then read as the original config. 2309398260262f8508687614ec496a23b8152bcdc967bsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 23106c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 23116c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon tempDrawInfo->fReadConfig = srcConfig; 2312f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 23131aa202935ff698f1f35c5435455073fd9f1d08debsalomon } else if (!this->readPixelsSupported(srcSurface, readConfig)) { 23141aa202935ff698f1f35c5435455073fd9f1d08debsalomon if (readConfig == kBGRA_8888_GrPixelConfig && 231571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig) && 23161aa202935ff698f1f35c5435455073fd9f1d08debsalomon this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPixelConfig)) { 2317e9573317d35d08254412eb407211f3607f8f74fbbsalomon // We're trying to read BGRA but it's not supported. If RGBA is renderable and 2318e9573317d35d08254412eb407211f3607f8f74fbbsalomon // we can read it back, then do a swizzling draw to a RGBA and read it back (which 2319e9573317d35d08254412eb407211f3607f8f74fbbsalomon // will effectively be BGRA). 23201aa202935ff698f1f35c5435455073fd9f1d08debsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; 23211aa202935ff698f1f35c5435455073fd9f1d08debsalomon tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 23221aa202935ff698f1f35c5435455073fd9f1d08debsalomon tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig; 23231aa202935ff698f1f35c5435455073fd9f1d08debsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2324a6359365887048ef055196de75591311d7a015f0brianosman } else if (readConfig == kSBGRA_8888_GrPixelConfig && 232571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) && 2326a6359365887048ef055196de75591311d7a015f0brianosman this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, kSRGBA_8888_GrPixelConfig)) { 2327a6359365887048ef055196de75591311d7a015f0brianosman // We're trying to read sBGRA but it's not supported. If sRGBA is renderable and 2328a6359365887048ef055196de75591311d7a015f0brianosman // we can read it back, then do a swizzling draw to a sRGBA and read it back (which 2329a6359365887048ef055196de75591311d7a015f0brianosman // will effectively be sBGRA). 2330a6359365887048ef055196de75591311d7a015f0brianosman tempDrawInfo->fTempSurfaceDesc.fConfig = kSRGBA_8888_GrPixelConfig; 2331a6359365887048ef055196de75591311d7a015f0brianosman tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2332a6359365887048ef055196de75591311d7a015f0brianosman tempDrawInfo->fReadConfig = kSRGBA_8888_GrPixelConfig; 2333a6359365887048ef055196de75591311d7a015f0brianosman ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2334e9573317d35d08254412eb407211f3607f8f74fbbsalomon } else if (readConfig == kAlpha_8_GrPixelConfig) { 2335e9573317d35d08254412eb407211f3607f8f74fbbsalomon // onReadPixels implements a fallback for cases where we are want to read kAlpha_8, 2336e9573317d35d08254412eb407211f3607f8f74fbbsalomon // it's unsupported, but 32bit RGBA reads are supported. 2337e9573317d35d08254412eb407211f3607f8f74fbbsalomon // Don't attempt to do any srgb conversions since we only care about alpha. 2338e9573317d35d08254412eb407211f3607f8f74fbbsalomon GrPixelConfig cpuTempConfig = kRGBA_8888_GrPixelConfig; 2339e9573317d35d08254412eb407211f3607f8f74fbbsalomon if (GrPixelConfigIsSRGB(srcSurface->config())) { 2340e9573317d35d08254412eb407211f3607f8f74fbbsalomon cpuTempConfig = kSRGBA_8888_GrPixelConfig; 2341e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2342e9573317d35d08254412eb407211f3607f8f74fbbsalomon if (!this->readPixelsSupported(srcSurface, cpuTempConfig)) { 2343e9573317d35d08254412eb407211f3607f8f74fbbsalomon // If we can't read RGBA from the src try to draw to a kRGBA_8888 (or kSRGBA_8888) 2344e9573317d35d08254412eb407211f3607f8f74fbbsalomon // first and then onReadPixels will read that to a 32bit temporary buffer. 234571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (this->glCaps().canConfigBeFBOColorAttachment(cpuTempConfig)) { 2346e9573317d35d08254412eb407211f3607f8f74fbbsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2347e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = cpuTempConfig; 2348e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempDrawInfo->fReadConfig = kAlpha_8_GrPixelConfig; 2349e9573317d35d08254412eb407211f3607f8f74fbbsalomon } else { 2350e9573317d35d08254412eb407211f3607f8f74fbbsalomon return false; 2351e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2352e9573317d35d08254412eb407211f3607f8f74fbbsalomon } else { 2353e9573317d35d08254412eb407211f3607f8f74fbbsalomon SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig); 2354e9573317d35d08254412eb407211f3607f8f74fbbsalomon SkASSERT(tempDrawInfo->fReadConfig == kAlpha_8_GrPixelConfig); 2355e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 235671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon } else if (this->glCaps().canConfigBeFBOColorAttachment(readConfig) && 2357e6d665e24feabf6c633452885910efd17e5f025ebsalomon this->readPixelsSupported(readConfig, readConfig)) { 2358e6d665e24feabf6c633452885910efd17e5f025ebsalomon // Do a draw to convert from the src config to the read config. 2359e6d665e24feabf6c633452885910efd17e5f025ebsalomon ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2360e6d665e24feabf6c633452885910efd17e5f025ebsalomon tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; 2361e6d665e24feabf6c633452885910efd17e5f025ebsalomon tempDrawInfo->fReadConfig = readConfig; 23621aa202935ff698f1f35c5435455073fd9f1d08debsalomon } else { 23631aa202935ff698f1f35c5435455073fd9f1d08debsalomon return false; 23641aa202935ff698f1f35c5435455073fd9f1d08debsalomon } 2365398260262f8508687614ec496a23b8152bcdc967bsalomon } 2366398260262f8508687614ec496a23b8152bcdc967bsalomon 236771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if ((srcSurface->asRenderTarget() || this->glCaps().canConfigBeFBOColorAttachment(srcConfig)) && 236871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon read_pixels_pays_for_y_flip(srcSurface->origin(), this->glCaps(), width, height, readConfig, 236971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon rowBytes)) { 2370f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2371398260262f8508687614ec496a23b8152bcdc967bsalomon } 2372398260262f8508687614ec496a23b8152bcdc967bsalomon 2373398260262f8508687614ec496a23b8152bcdc967bsalomon return true; 2374c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com} 2375c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 23766cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomonbool GrGLGpu::onReadPixels(GrSurface* surface, 2377c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int left, int top, 2378c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int width, int height, 2379c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrPixelConfig config, 2380c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com void* buffer, 23813cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org size_t rowBytes) { 23826cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon SkASSERT(surface); 2383398260262f8508687614ec496a23b8152bcdc967bsalomon 2384e9573317d35d08254412eb407211f3607f8f74fbbsalomon GrGLRenderTarget* renderTarget = static_cast<GrGLRenderTarget*>(surface->asRenderTarget()); 238571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (!renderTarget && !this->glCaps().canConfigBeFBOColorAttachment(surface->config())) { 23866cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon return false; 23876cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon } 23886cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon 238916921ec30a81976129d507b1148c93a322e61a4fbsalomon // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels. 2390e9573317d35d08254412eb407211f3607f8f74fbbsalomon if (requires_srgb_conversion(surface->config(), config)) { 2391e9573317d35d08254412eb407211f3607f8f74fbbsalomon return false; 2392e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2393e9573317d35d08254412eb407211f3607f8f74fbbsalomon 2394e9573317d35d08254412eb407211f3607f8f74fbbsalomon // We have a special case fallback for reading eight bit alpha. We will read back all four 8 2395e9573317d35d08254412eb407211f3607f8f74fbbsalomon // bit channels as RGBA and then extract A. 239671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (!this->readPixelsSupported(surface, config)) { 2397e9573317d35d08254412eb407211f3607f8f74fbbsalomon // Don't attempt to do any srgb conversions since we only care about alpha. 2398e9573317d35d08254412eb407211f3607f8f74fbbsalomon GrPixelConfig tempConfig = kRGBA_8888_GrPixelConfig; 239971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (GrPixelConfigIsSRGB(surface->config())) { 2400e9573317d35d08254412eb407211f3607f8f74fbbsalomon tempConfig = kSRGBA_8888_GrPixelConfig; 2401e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2402e9573317d35d08254412eb407211f3607f8f74fbbsalomon if (kAlpha_8_GrPixelConfig == config && 240371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->readPixelsSupported(surface, tempConfig)) { 24047ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner std::unique_ptr<uint32_t[]> temp(new uint32_t[width * height * 4]); 240571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (this->onReadPixels(surface, left, top, width, height, tempConfig, temp.get(), 2406e9573317d35d08254412eb407211f3607f8f74fbbsalomon width*4)) { 2407e9573317d35d08254412eb407211f3607f8f74fbbsalomon uint8_t* dst = reinterpret_cast<uint8_t*>(buffer); 2408e9573317d35d08254412eb407211f3607f8f74fbbsalomon for (int j = 0; j < height; ++j) { 2409e9573317d35d08254412eb407211f3607f8f74fbbsalomon for (int i = 0; i < width; ++i) { 2410e9573317d35d08254412eb407211f3607f8f74fbbsalomon dst[j*rowBytes + i] = (0xFF000000U & temp[j*width+i]) >> 24; 2411e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2412e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2413e9573317d35d08254412eb407211f3607f8f74fbbsalomon return true; 2414e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 2415e9573317d35d08254412eb407211f3607f8f74fbbsalomon } 241616921ec30a81976129d507b1148c93a322e61a4fbsalomon return false; 241716921ec30a81976129d507b1148c93a322e61a4fbsalomon } 241816921ec30a81976129d507b1148c93a322e61a4fbsalomon 241976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalFormat; 242076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalType; 242171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (!this->glCaps().getReadPixelsFormat(surface->config(), config, &externalFormat, 242276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon &externalType)) { 242376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon return false; 242476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon } 24256cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); 2426c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 242771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon GrGLIRect glvp; 242871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (renderTarget) { 242971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon // resolve the render target if necessary 243071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon switch (renderTarget->getResolveType()) { 243171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon case GrGLRenderTarget::kCantResolve_ResolveType: 243271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon return false; 243371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon case GrGLRenderTarget::kAutoResolves_ResolveType: 243471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->flushRenderTarget(renderTarget, &SkIRect::EmptyIRect()); 243571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon break; 243671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon case GrGLRenderTarget::kCanResolve_ResolveType: 243771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->onResolveRenderTarget(renderTarget); 243871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon // we don't track the state of the READ FBO ID. 243971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon fStats.incRenderTargetBinds(); 244071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID())); 244171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon break; 244271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon default: 244371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon SkFAIL("Unknown resolve type"); 244471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon } 244571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon glvp = renderTarget->getViewport(); 244671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon } else { 244771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon // Use a temporary FBO. 244871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->bindSurfaceFBOForPixelOps(surface, GR_GL_FRAMEBUFFER, &glvp, kSrc_TempFBOTarget); 2449294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 24506ba6fa15261be591f33cf0e5df7134e4fc6432acbsalomon } 2451ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 24528895a7a0e222de4530e506e43eaa5e6030e8c5edbsalomon@google.com // the read rect is viewport-relative 24538895a7a0e222de4530e506e43eaa5e6030e8c5edbsalomon@google.com GrGLIRect readRect; 245471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon readRect.setRelativeTo(glvp, left, top, width, height, surface->origin()); 2455fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 24569d02b264b72be64702e43cb797b7899a8a6926cabsalomon size_t bytesPerPixel = GrBytesPerPixel(config); 24579d02b264b72be64702e43cb797b7899a8a6926cabsalomon size_t tightRowBytes = bytesPerPixel * width; 24586d901da0ec4b10010eca05114ab8f9564bd04af3egdaniel 2459c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com size_t readDstRowBytes = tightRowBytes; 2460c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com void* readDst = buffer; 2461fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2462c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // determine if GL can read using the passed rowBytes or if we need 2463c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // a scratch buffer. 246429f8679068ecbd693e123a59b09a5ade3cfde996joshualitt SkAutoSMalloc<32 * sizeof(GrColor)> scratch; 2465c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (rowBytes != tightRowBytes) { 24669d02b264b72be64702e43cb797b7899a8a6926cabsalomon if (this->glCaps().packRowLengthSupport() && !(rowBytes % bytesPerPixel)) { 24674677acc75915ebd32ee0efed5c7b41da2a9d047cskia.committer@gmail.com GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 24689d02b264b72be64702e43cb797b7899a8a6926cabsalomon static_cast<GrGLint>(rowBytes / bytesPerPixel))); 2469c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com readDstRowBytes = rowBytes; 2470c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } else { 2471c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com scratch.reset(tightRowBytes * height); 2472c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com readDst = scratch.get(); 2473c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 2474c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 24753cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (flipY && this->glCaps().packFlipYSupport()) { 247656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1)); 247756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 2478f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon GL_CALL(PixelStorei(GR_GL_PACK_ALIGNMENT, config_alignment(config))); 2479f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon 24800b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom, 24810b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com readRect.fWidth, readRect.fHeight, 248276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon externalFormat, externalType, readDst)); 2483c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (readDstRowBytes != tightRowBytes) { 2484f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(this->glCaps().packRowLengthSupport()); 2485c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); 2486c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 24873cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (flipY && this->glCaps().packFlipYSupport()) { 248856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0)); 24893cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org flipY = false; 249056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 2491ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2492ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // now reverse the order of the rows, since GL's are bottom-to-top, but our 2493c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // API presents top-to-bottom. We must preserve the padding contents. Note 2494c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // that the above readPixels did not overwrite the padding. 2495c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (readDst == buffer) { 2496f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(rowBytes == readDstRowBytes); 24973cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (flipY) { 2498c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com scratch.reset(tightRowBytes); 2499c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com void* tmpRow = scratch.get(); 2500c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // flip y in-place by rows 2501c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com const int halfY = height >> 1; 2502c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com char* top = reinterpret_cast<char*>(buffer); 2503c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com char* bottom = top + (height - 1) * rowBytes; 2504c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com for (int y = 0; y < halfY; y++) { 2505c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com memcpy(tmpRow, top, tightRowBytes); 2506c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com memcpy(top, bottom, tightRowBytes); 2507c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com memcpy(bottom, tmpRow, tightRowBytes); 2508c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com top += rowBytes; 2509c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com bottom -= rowBytes; 2510c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 2511c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 2512c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } else { 25139d02b264b72be64702e43cb797b7899a8a6926cabsalomon SkASSERT(readDst != buffer); 25149d02b264b72be64702e43cb797b7899a8a6926cabsalomon SkASSERT(rowBytes != tightRowBytes); 2515c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // copy from readDst to buffer while flipping y 2516cf6285b89b8820641ffb6871d4b3275bfe783f51caryclark@google.com // const int halfY = height >> 1; 2517c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com const char* src = reinterpret_cast<const char*>(readDst); 2518c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com char* dst = reinterpret_cast<char*>(buffer); 25193cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (flipY) { 2520c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com dst += (height-1) * rowBytes; 2521c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 2522c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int y = 0; y < height; y++) { 2523c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com memcpy(dst, src, tightRowBytes); 2524c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com src += readDstRowBytes; 25253cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (!flipY) { 2526c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com dst += rowBytes; 2527c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } else { 2528c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com dst -= rowBytes; 2529c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 2530ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 2531ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 253271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (!renderTarget) { 253371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, surface); 253471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon } 2535ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return true; 2536ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2537ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 25389cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpuCommandBuffer* GrGLGpu::createCommandBuffer( 25399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo, 25409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) { 2541c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon return new GrGLGpuCommandBuffer(this); 2542066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 2543066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 254464d094d7756534a9b9b0997aab225d9ceba098b6brianosmanvoid GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bounds, bool disableSRGB) { 2545d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel SkASSERT(target); 25462e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com 2547294870ff119b89fc902773643b054f14e5d1f554Robert Phillips GrGpuResource::UniqueID rtID = target->uniqueID(); 2548d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (fHWBoundRenderTargetUniqueID != rtID) { 25491e0bf7e113f994a512a351cc2b25ddb1e742b7d4bsalomon fStats.incRenderTargetBinds(); 2550d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); 2551d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel#ifdef SK_DEBUG 2552d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // don't do this check in Chromium -- this is causing 2553d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // lots of repeated command buffer flushes when the compositor is 2554d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // rendering with Ganesh, which is really slow; even too slow for 2555d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // Debug mode. 25561acea86914797bc33856ff62b5cdfbe82c58dd67cdalton if (kChromium_GrGLDriver != this->glContext().driver()) { 2557d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GrGLenum status; 2558d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 2559d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 2560d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x\n", status); 2561d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel } 2562d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel } 2563d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel#endif 2564d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fHWBoundRenderTargetUniqueID = rtID; 2565083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon this->flushViewport(target->getViewport()); 256664d094d7756534a9b9b0997aab225d9ceba098b6brianosman } 256764d094d7756534a9b9b0997aab225d9ceba098b6brianosman 256835b784d48f59be3a3ee28d9d73e03c7f8835d2f9brianosman if (this->glCaps().srgbWriteControl()) { 256933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !disableSRGB); 25701e0bf7e113f994a512a351cc2b25ddb1e742b7d4bsalomon } 257164d094d7756534a9b9b0997aab225d9ceba098b6brianosman 2572083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon this->didWriteToSurface(target, bounds); 2573083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon} 2574083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon 257533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosmanvoid GrGLGpu::flushFramebufferSRGB(bool enable) { 257633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (enable && kYes_TriState != fHWSRGBFramebuffer) { 257733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB)); 257833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fHWSRGBFramebuffer = kYes_TriState; 257933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) { 258033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); 258133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fHWSRGBFramebuffer = kNo_TriState; 258233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 258333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman} 258433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 2585083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomonvoid GrGLGpu::flushViewport(const GrGLIRect& viewport) { 2586083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon if (fHWViewport != viewport) { 2587083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon viewport.pushToGLViewport(this->glInterface()); 2588083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon fHWViewport = viewport; 2589083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon } 2590083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon} 2591a9909121ebdd35fb8d8694103a443f230ffa3a3absalomon 25920f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.comGrGLenum gPrimitiveType2GLMode[] = { 25930f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_TRIANGLES, 25940f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_TRIANGLE_STRIP, 25950f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_TRIANGLE_FAN, 25960f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_POINTS, 25970f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_LINES, 25980f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com GR_GL_LINE_STRIP 2599ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}; 2600ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2601d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#define SWAP_PER_DRAW 0 2602d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 2603a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com#if SWAP_PER_DRAW 26044382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org #if defined(SK_BUILD_FOR_MAC) 2605d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com #include <AGL/agl.h> 26064382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org #elif defined(SK_BUILD_FOR_WIN32) 2607ce7357df6aa2d73c6e74313af767db7b608fe0a5bsalomon@google.com #include <gl/GL.h> 2608d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com void SwapBuf() { 2609d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com DWORD procID = GetCurrentProcessId(); 2610d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com HWND hwnd = GetTopWindow(GetDesktopWindow()); 2611d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com while(hwnd) { 2612d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com DWORD wndProcID = 0; 2613d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GetWindowThreadProcessId(hwnd, &wndProcID); 2614d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com if(wndProcID == procID) { 2615d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com SwapBuffers(GetDC(hwnd)); 2616d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com } 2617d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); 2618d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com } 2619d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com } 2620d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com #endif 2621d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#endif 2622d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 26239cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrGLGpu::draw(const GrPipeline& pipeline, 26249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrPrimitiveProcessor& primProc, 26252eda5b3a65f54105ae3776160373eed5500c515fbsalomon const GrMesh meshes[], 26269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel int meshCount) { 26279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel this->handleDirtyContext(); 26289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 26292eda5b3a65f54105ae3776160373eed5500c515fbsalomon bool hasPoints = false; 26302eda5b3a65f54105ae3776160373eed5500c515fbsalomon for (int i = 0; i < meshCount; ++i) { 26312eda5b3a65f54105ae3776160373eed5500c515fbsalomon if (meshes[i].primitiveType() == kPoints_GrPrimitiveType) { 26322eda5b3a65f54105ae3776160373eed5500c515fbsalomon hasPoints = true; 26332eda5b3a65f54105ae3776160373eed5500c515fbsalomon break; 26342eda5b3a65f54105ae3776160373eed5500c515fbsalomon } 26352eda5b3a65f54105ae3776160373eed5500c515fbsalomon } 26362eda5b3a65f54105ae3776160373eed5500c515fbsalomon if (!this->flushGLState(pipeline, primProc, hasPoints)) { 2637d95263c60e1c3b9e337d777d6f3cf286c1dc43f6bsalomon return; 2638d95263c60e1c3b9e337d777d6f3cf286c1dc43f6bsalomon } 26392279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas 26400e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel for (int i = 0; i < meshCount; ++i) { 26410e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) { 26420e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel this->xferBarrier(pipeline.getRenderTarget(), barrierType); 26430e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 26440e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 26450e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrMesh& mesh = meshes[i]; 26460e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrMesh::Iterator iter; 2647fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon const GrNonInstancedMesh* nonInstMesh = iter.init(mesh); 26480e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel do { 26490e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel size_t indexOffsetInBytes = 0; 2650fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon this->setupGeometry(primProc, *nonInstMesh, &indexOffsetInBytes); 2651fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon if (nonInstMesh->isIndexed()) { 26520e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrGLvoid* indices = 2653fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + 2654fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon sizeof(uint16_t) * nonInstMesh->startIndex()); 26550e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel // info.startVertex() was accounted for by setupGeometry. 2656fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon if (this->glCaps().drawRangeElementsSupport()) { 265709d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon // We assume here that the GrMeshDrawOps that generated the mesh used the full 2658fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon // 0..vertexCount()-1 range. 2659fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon int start = 0; 2660fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon int end = nonInstMesh->vertexCount() - 1; 2661fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon GL_CALL(DrawRangeElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()], 2662fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon start, end, 2663fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon nonInstMesh->indexCount(), 2664fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon GR_GL_UNSIGNED_SHORT, 2665fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon indices)); 2666fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon } else { 2667fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon GL_CALL(DrawElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()], 2668fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon nonInstMesh->indexCount(), 2669fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon GR_GL_UNSIGNED_SHORT, 2670fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon indices)); 2671fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon } 26720e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } else { 26730e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account 26740e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel // for startVertex in the DrawElements case. So we always rely on setupGeometry to 26750e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel // have accounted for startVertex. 2676fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonInstMesh->primitiveType()], 0, 2677fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon nonInstMesh->vertexCount())); 26780e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 26790e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel fStats.incNumDraws(); 2680fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon } while ((nonInstMesh = iter.next())); 268174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com } 26822279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas 2683d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#if SWAP_PER_DRAW 2684d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com glFlush(); 26854382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org #if defined(SK_BUILD_FOR_MAC) 2686d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com aglSwapBuffers(aglGetCurrentContext()); 2687d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com int set_a_break_pt_here = 9; 2688d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com aglSwapBuffers(aglGetCurrentContext()); 26894382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org #elif defined(SK_BUILD_FOR_WIN32) 2690d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com SwapBuf(); 2691d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com int set_a_break_pt_here = 9; 2692d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com SwapBuf(); 2693d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com #endif 2694d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#endif 2695ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2696ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2697861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { 269875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); 26995877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com if (rt->needsResolve()) { 2700347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com // Some extensions automatically resolves the texture when it is read. 2701347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com if (this->glCaps().usesMSAARenderBuffers()) { 2702d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel SkASSERT(rt->textureFBOID() != rt->renderFBOID()); 2703d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fStats.incRenderTargetBinds(); 2704d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fStats.incRenderTargetBinds(); 2705d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); 2706d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID())); 2707d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // make sure we go through flushRenderTarget() since we've modified 2708d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel // the bound DRAW FBO ID. 2709294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 2710f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com const GrGLIRect& vp = rt->getViewport(); 2711fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkIRect dirtyRect = rt->getResolveRect(); 2712f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com 2713347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { 2714f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com // Apple's extension uses the scissor as the blit bounds. 27153e79124a69d4806f0a1a776090bff718e1b90970bsalomon GrScissorState scissorState; 2716e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips scissorState.set(dirtyRect); 2717e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips this->flushScissor(scissorState, vp, rt->origin()); 271828341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton this->disableWindowRectangles(); 2719f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com GL_CALL(ResolveMultisampleFramebuffer()); 2720f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com } else { 2721e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon int l, b, r, t; 2722e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & 2723e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon this->glCaps().blitFramebufferSupportFlags()) { 2724e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon l = 0; 2725e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon b = 0; 2726e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon r = target->width(); 2727e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon t = target->height(); 2728e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } else { 2729e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon GrGLIRect rect; 2730e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon rect.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop, 2731e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon dirtyRect.width(), dirtyRect.height(), target->origin()); 2732e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon l = rect.fLeft; 2733e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon b = rect.fBottom; 2734e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon r = rect.fLeft + rect.fWidth; 2735e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon t = rect.fBottom + rect.fHeight; 2736e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 27378c8f71ac07f0611d2c3ec53551c7e0f6a1cc4789derekf 27388c8f71ac07f0611d2c3ec53551c7e0f6a1cc4789derekf // BlitFrameBuffer respects the scissor, so disable it. 273977b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt this->disableScissor(); 274028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton this->disableWindowRectangles(); 2741e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, 2742f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 2743a9ecdadfbcc06ccfd40f13aa2d7b563a64520060bsalomon@google.com } 2744ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 27455877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com rt->flagAsResolved(); 2746ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 2747ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2748ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2749411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.comnamespace { 2750411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com 2751411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com 2752411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.comGrGLenum gr_to_gl_stencil_op(GrStencilOp op) { 275393a379bd4d6b30d86c270b879cf172d80172a72bcdalton static const GrGLenum gTable[kGrStencilOpCount] = { 275493a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_KEEP, // kKeep 275593a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_ZERO, // kZero 275693a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_REPLACE, // kReplace 275793a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_INVERT, // kInvert 275893a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_INCR_WRAP, // kIncWrap 275993a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_DECR_WRAP, // kDecWrap 276093a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_INCR, // kIncClamp 276193a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_GL_DECR, // kDecClamp 2762411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com }; 276393a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(0 == (int)GrStencilOp::kKeep); 276493a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(1 == (int)GrStencilOp::kZero); 276593a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(2 == (int)GrStencilOp::kReplace); 276693a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(3 == (int)GrStencilOp::kInvert); 276793a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(4 == (int)GrStencilOp::kIncWrap); 276893a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(5 == (int)GrStencilOp::kDecWrap); 276993a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(6 == (int)GrStencilOp::kIncClamp); 277093a379bd4d6b30d86c270b879cf172d80172a72bcdalton GR_STATIC_ASSERT(7 == (int)GrStencilOp::kDecClamp); 277193a379bd4d6b30d86c270b879cf172d80172a72bcdalton SkASSERT(op < (GrStencilOp)kGrStencilOpCount); 277293a379bd4d6b30d86c270b879cf172d80172a72bcdalton return gTable[(int)op]; 2773411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com} 2774411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com 2775411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.comvoid set_gl_stencil(const GrGLInterface* gl, 277693a379bd4d6b30d86c270b879cf172d80172a72bcdalton const GrStencilSettings::Face& face, 277793a379bd4d6b30d86c270b879cf172d80172a72bcdalton GrGLenum glFace) { 277893a379bd4d6b30d86c270b879cf172d80172a72bcdalton GrGLenum glFunc = GrToGLStencilFunc(face.fTest); 277993a379bd4d6b30d86c270b879cf172d80172a72bcdalton GrGLenum glFailOp = gr_to_gl_stencil_op(face.fFailOp); 278093a379bd4d6b30d86c270b879cf172d80172a72bcdalton GrGLenum glPassOp = gr_to_gl_stencil_op(face.fPassOp); 2781a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com 278293a379bd4d6b30d86c270b879cf172d80172a72bcdalton GrGLint ref = face.fRef; 278393a379bd4d6b30d86c270b879cf172d80172a72bcdalton GrGLint mask = face.fTestMask; 278493a379bd4d6b30d86c270b879cf172d80172a72bcdalton GrGLint writeMask = face.fWriteMask; 2785411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com 2786411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com if (GR_GL_FRONT_AND_BACK == glFace) { 2787411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com // we call the combined func just in case separate stencil is not 2788411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com // supported. 2789411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask)); 2790411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com GR_GL_CALL(gl, StencilMask(writeMask)); 2791c5d58f07aa6f4c47337d769e0e2e69c79669f91avbuzinov GR_GL_CALL(gl, StencilOp(glFailOp, GR_GL_KEEP, glPassOp)); 2792411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com } else { 2793411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask)); 2794411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask)); 2795c5d58f07aa6f4c47337d769e0e2e69c79669f91avbuzinov GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, GR_GL_KEEP, glPassOp)); 2796411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com } 2797411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com} 2798411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com} 2799d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 28003e79124a69d4806f0a1a776090bff718e1b90970bsalomonvoid GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings) { 2801c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton if (stencilSettings.isDisabled()) { 2802c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton this->disableStencil(); 2803c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton } else if (fHWStencilSettings != stencilSettings) { 2804c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton if (kYes_TriState != fHWStencilTestEnabled) { 2805c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton GL_CALL(Enable(GR_GL_STENCIL_TEST)); 2806c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton fHWStencilTestEnabled = kYes_TriState; 2807a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com } 2808c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton if (stencilSettings.isTwoSided()) { 2809c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton SkASSERT(this->caps()->twoSidedStencilSupport()); 2810c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton set_gl_stencil(this->glInterface(), 2811c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton stencilSettings.front(), 2812c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton GR_GL_FRONT); 2813c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton set_gl_stencil(this->glInterface(), 2814c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton stencilSettings.back(), 2815c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton GR_GL_BACK); 2816c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton } else { 2817c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton set_gl_stencil(this->glInterface(), 2818c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton stencilSettings.front(), 2819c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton GR_GL_FRONT_AND_BACK); 2820ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 2821a58fe35fdae3481cf43062f7032820c320c3d163joshualitt fHWStencilSettings = stencilSettings; 2822ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 2823ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 2824ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2825c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdaltonvoid GrGLGpu::disableStencil() { 2826c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton if (kNo_TriState != fHWStencilTestEnabled) { 2827c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton GL_CALL(Disable(GR_GL_STENCIL_TEST)); 2828c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton fHWStencilTestEnabled = kNo_TriState; 2829c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton fHWStencilSettings.invalidate(); 2830c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton } 2831c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton} 2832c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton 2833af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdaltonvoid GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled) { 2834083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon // rt is only optional if useHWAA is false. 2835083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon SkASSERT(rt || !useHWAA); 2836dded69693dd3779f081326cde24c3954505b129dvbuzinov SkASSERT(!useHWAA || rt->isStencilBufferMultisampled()); 2837202d139452bed846a81cd89bbb3808ded0b3d64fbsalomon@google.com 28382b5f2cbf0d0b580e5277d1d085ce261cb5233111csmartdalton if (this->caps()->multisampleDisableSupport()) { 2839d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton if (useHWAA) { 2840d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton if (kYes_TriState != fMSAAEnabled) { 2841d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton GL_CALL(Enable(GR_GL_MULTISAMPLE)); 2842d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton fMSAAEnabled = kYes_TriState; 2843d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton } 2844d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton } else { 2845d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton if (kNo_TriState != fMSAAEnabled) { 2846d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton GL_CALL(Disable(GR_GL_MULTISAMPLE)); 2847d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton fMSAAEnabled = kNo_TriState; 2848f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com } 2849f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com } 2850f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com } 2851af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton 2852af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton if (0 != this->caps()->maxRasterSamples()) { 2853f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton if (useHWAA && rt->isMixedSampled() && !stencilEnabled) { 2854af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton // Since stencil is disabled and we want more samples than are in the color buffer, we 2855af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton // need to tell the rasterizer explicitly how many to run. 2856af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton if (kYes_TriState != fHWRasterMultisampleEnabled) { 2857af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton GL_CALL(Enable(GR_GL_RASTER_MULTISAMPLE)); 2858af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton fHWRasterMultisampleEnabled = kYes_TriState; 2859af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } 2860af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton if (rt->numStencilSamples() != fHWNumRasterSamples) { 2861af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton SkASSERT(rt->numStencilSamples() <= this->caps()->maxRasterSamples()); 2862af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton GL_CALL(RasterSamples(rt->numStencilSamples(), GR_GL_TRUE)); 2863af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton fHWNumRasterSamples = rt->numStencilSamples(); 2864af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } 2865af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } else { 2866af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton if (kNo_TriState != fHWRasterMultisampleEnabled) { 2867af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton GL_CALL(Disable(GR_GL_RASTER_MULTISAMPLE)); 2868af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton fHWRasterMultisampleEnabled = kNo_TriState; 2869af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } 2870af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } 2871af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } else { 2872f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton SkASSERT(!useHWAA || !rt->isMixedSampled() || stencilEnabled); 2873af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton } 2874f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com} 2875f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com 28767f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomonvoid GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) { 2877b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel // Any optimization to disable blending should have already been applied and 28788917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton // tweaked the equation to "add" or "subtract", and the coeffs to (1, 0). 2879f7cc87719e53df86784d0d953b88c45a3be38953bsalomon 28808917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GrBlendEquation equation = blendInfo.fEquation; 2881c230414861558ce20b74281b1ca363e56c441832egdaniel GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 2882c230414861558ce20b74281b1ca363e56c441832egdaniel GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 28838917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && 28848917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; 2885b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel if (blendOff) { 2886b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel if (kNo_TriState != fHWBlendState.fEnabled) { 2887b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel GL_CALL(Disable(GR_GL_BLEND)); 28889764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang 28899764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang // Workaround for the ARM KHR_blend_equation_advanced blacklist issue 28909764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang // https://code.google.com/p/skia/issues/detail?id=3943 28919764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang if (kARM_GrGLVendor == this->ctxInfo().vendor() && 28929764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang GrBlendEquationIsAdvanced(fHWBlendState.fEquation)) { 28939764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang SkASSERT(this->caps()->advancedBlendEquationSupport()); 28949764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang // Set to any basic blending equation. 28959764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang GrBlendEquation blend_equation = kAdd_GrBlendEquation; 28969764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang GL_CALL(BlendEquation(gXfermodeEquation2Blend[blend_equation])); 28979764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang fHWBlendState.fEquation = blend_equation; 28989764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang } 28999764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang 2900b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel fHWBlendState.fEnabled = kNo_TriState; 2901b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel } 29028917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton return; 29038917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton } 29048917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton 29058917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton if (kYes_TriState != fHWBlendState.fEnabled) { 29068917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GL_CALL(Enable(GR_GL_BLEND)); 29078917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton fHWBlendState.fEnabled = kYes_TriState; 29088917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton } 29098917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton 29108917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton if (fHWBlendState.fEquation != equation) { 29118917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GL_CALL(BlendEquation(gXfermodeEquation2Blend[equation])); 29128917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton fHWBlendState.fEquation = equation; 29138917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton } 29148917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton 29158917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton if (GrBlendEquationIsAdvanced(equation)) { 29168917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton SkASSERT(this->caps()->advancedBlendEquationSupport()); 29178917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton // Advanced equations have no other blend state. 29188917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton return; 29198917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton } 29208917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton 2921e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon if (fHWBlendState.fSrcCoeff != srcCoeff || fHWBlendState.fDstCoeff != dstCoeff) { 29228917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], 29238917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton gXfermodeCoeff2Blend[dstCoeff])); 29248917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton fHWBlendState.fSrcCoeff = srcCoeff; 29258917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton fHWBlendState.fDstCoeff = dstCoeff; 29268917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton } 29278917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton 29287f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff))) { 29297f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon GrColor blendConst = blendInfo.fBlendConstant; 29307f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon blendConst = swizzle.applyTo(blendConst); 29317f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon if (!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst) { 29327f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon GrGLfloat c[4]; 29337f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon GrColorToRGBAFloat(blendConst, c); 29347f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); 29357f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon fHWBlendState.fConstColor = blendConst; 29367f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon fHWBlendState.fConstColorValid = true; 29377f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon } 29380650e811b537f21a3a9d09a953960626cf5cfce4bsalomon@google.com } 29390650e811b537f21a3a9d09a953960626cf5cfce4bsalomon@google.com} 2940b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com 29416364b5edc3adb4ec0b26e507a474a2066977c509commit-bot@chromium.orgstatic inline GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) { 2942b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com static const GrGLenum gWrapModes[] = { 2943b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GR_GL_CLAMP_TO_EDGE, 2944b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GR_GL_REPEAT, 2945b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GR_GL_MIRRORED_REPEAT 2946b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com }; 29475d7ca957edcc57f7f0be2741183e8d3c36cb5129commit-bot@chromium.org GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes)); 2948b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode); 2949b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode); 2950b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode); 2951b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com return gWrapModes[tm]; 2952b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com} 2953b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com 2954b7e7d5748d74c7482436b33733d7770484bb62e3egdanielstatic GrGLenum get_component_enum_from_char(char component) { 2955b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel switch (component) { 2956b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel case 'r': 2957b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel return GR_GL_RED; 2958b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel case 'g': 2959b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel return GR_GL_GREEN; 2960b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel case 'b': 2961b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel return GR_GL_BLUE; 2962b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel case 'a': 2963b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel return GR_GL_ALPHA; 2964b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel default: 2965b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel SkFAIL("Unsupported component"); 2966b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel return 0; 2967b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel } 2968b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel} 2969b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel 2970b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel/** If texture swizzling is available using tex parameters then it is preferred over mangling 2971b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel the generated shader code. This potentially allows greater reuse of cached shaders. */ 2972b7e7d5748d74c7482436b33733d7770484bb62e3egdanielstatic void get_tex_param_swizzle(GrPixelConfig config, 2973cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon const GrGLCaps& caps, 2974b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel GrGLenum* glSwizzle) { 2975cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon const GrSwizzle& swizzle = caps.configSwizzle(config); 2976b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel for (int i = 0; i < 4; ++i) { 2977cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon glSwizzle[i] = get_component_enum_from_char(swizzle.c_str()[i]); 2978574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel } 2979574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel} 2980574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel 2981514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomonvoid GrGLGpu::bindTexture(int unitIdx, const GrSamplerParams& params, bool allowSRGBInputs, 2982a6359365887048ef055196de75591311d7a015f0brianosman GrGLTexture* texture) { 298349f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(texture); 2984d0c1a06cb98dd4a009dfa79e37ba6ca23a8c180btomhudson@google.com 2985856e9d921462136da8562f8f122d42e114cd4710reed#ifdef SK_DEBUG 2986856e9d921462136da8562f8f122d42e114cd4710reed if (!this->caps()->npotTextureTileSupport()) { 2987856e9d921462136da8562f8f122d42e114cd4710reed const bool tileX = SkShader::kClamp_TileMode != params.getTileModeX(); 2988856e9d921462136da8562f8f122d42e114cd4710reed const bool tileY = SkShader::kClamp_TileMode != params.getTileModeY(); 2989856e9d921462136da8562f8f122d42e114cd4710reed if (tileX || tileY) { 2990856e9d921462136da8562f8f122d42e114cd4710reed const int w = texture->width(); 2991856e9d921462136da8562f8f122d42e114cd4710reed const int h = texture->height(); 2992856e9d921462136da8562f8f122d42e114cd4710reed SkASSERT(SkIsPow2(w) && SkIsPow2(h)); 2993856e9d921462136da8562f8f122d42e114cd4710reed } 2994856e9d921462136da8562f8f122d42e114cd4710reed } 2995856e9d921462136da8562f8f122d42e114cd4710reed#endif 2996856e9d921462136da8562f8f122d42e114cd4710reed 2997b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com // If we created a rt/tex and rendered to it without using a texture and now we're texturing 2998b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com // from the rt it will still be the last bound texture, but it needs resolving. So keep this 29994c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com // out of the "last != next" check. 300037dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget()); 300149f085dddff10473b6ebf832a974288300224e60bsalomon if (texRT) { 30024c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com this->onResolveRenderTarget(texRT); 30034c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com } 30044c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 3005294870ff119b89fc902773643b054f14e5d1f554Robert Phillips GrGpuResource::UniqueID textureID = texture->uniqueID(); 300610528f1d5838ae1cac015024c4e8731484f888d1bsalomon GrGLenum target = texture->target(); 30071c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) { 300834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->setTextureUnit(unitIdx); 300910528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(BindTexture(target, texture->textureID())); 30101c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon fHWBoundTextureUniqueIDs[unitIdx] = textureID; 30114c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com } 30124c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 30134c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com ResetTimestamp timestamp; 301434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(×tamp); 30154c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com bool setAll = timestamp < this->getResetTimestamp(); 30164c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com GrGLTexture::TexParams newTexParams; 30174c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 3018149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org static GrGLenum glMinFilterModes[] = { 3019cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org GR_GL_NEAREST, 3020cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org GR_GL_LINEAR, 3021cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org GR_GL_LINEAR_MIPMAP_LINEAR 3022cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org }; 3023149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org static GrGLenum glMagFilterModes[] = { 3024149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org GR_GL_NEAREST, 3025149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org GR_GL_LINEAR, 3026149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org GR_GL_LINEAR 3027149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org }; 3028514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon GrSamplerParams::FilterMode filterMode = params.filterMode(); 3029efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon 3030514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon if (GrSamplerParams::kMipMap_FilterMode == filterMode) { 3031efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture->config())) { 3032514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon filterMode = GrSamplerParams::kBilerp_FilterMode; 3033efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon } 30344744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org } 3035efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon 30364744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org newTexParams.fMinFilter = glMinFilterModes[filterMode]; 30374744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org newTexParams.fMagFilter = glMagFilterModes[filterMode]; 3038aeefb2afe74c010c7236f3572e21a8f8a6aee1bdskia.committer@gmail.com 303920471894eaa441193d5ae8f2395e8244c91c55afbrianosman if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) { 3040fe19987e5499650e8637a8d109f19b8156601660brianosman newTexParams.fSRGBDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT; 304133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) { 3042adf4fa6fdef40071ebef11d767c2eb067af77179brianosman this->setTextureUnit(unitIdx); 304333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexParams.fSRGBDecode)); 304455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 3045cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org } 30464c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 304733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman#ifdef SK_DEBUG 304833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // We were supposed to ensure MipMaps were up-to-date and built correctly before getting here. 3049514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon if (GrSamplerParams::kMipMap_FilterMode == filterMode) { 305033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman SkASSERT(!texture->texturePriv().mipMapsAreDirty()); 305133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (GrPixelConfigIsSRGB(texture->config())) { 30527b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman SkDestinationSurfaceColorMode colorMode = allowSRGBInputs 30537b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware 30547b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman : SkDestinationSurfaceColorMode::kLegacy; 30557b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman SkASSERT(texture->texturePriv().mipColorMode() == colorMode); 305633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 305733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 305833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman#endif 305933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 306055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); 306155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume 3062b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); 3063b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); 3064cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizzleRGBA); 3065149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { 306634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->setTextureUnit(unitIdx); 306710528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMagFilter)); 3068149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org } 3069149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { 3070149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org this->setTextureUnit(unitIdx); 307110528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMinFilter)); 30724c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com } 307355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume if (setAll || newTexParams.fMaxMipMapLevel != oldTexParams.fMaxMipMapLevel) { 307409bd2c09b6b36737df289fdb5fa38c280162cbb8cblume // These are not supported in ES2 contexts 307509bd2c09b6b36737df289fdb5fa38c280162cbb8cblume if (this->glCaps().mipMapLevelAndLodControlSupport()) { 307609bd2c09b6b36737df289fdb5fa38c280162cbb8cblume if (newTexParams.fMaxMipMapLevel != 0) { 307709bd2c09b6b36737df289fdb5fa38c280162cbb8cblume this->setTextureUnit(unitIdx); 307809bd2c09b6b36737df289fdb5fa38c280162cbb8cblume GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0)); 307909bd2c09b6b36737df289fdb5fa38c280162cbb8cblume GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0)); 308009bd2c09b6b36737df289fdb5fa38c280162cbb8cblume GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LOD, 308109bd2c09b6b36737df289fdb5fa38c280162cbb8cblume newTexParams.fMaxMipMapLevel)); 308209bd2c09b6b36737df289fdb5fa38c280162cbb8cblume GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL, 308309bd2c09b6b36737df289fdb5fa38c280162cbb8cblume newTexParams.fMaxMipMapLevel)); 308409bd2c09b6b36737df289fdb5fa38c280162cbb8cblume } 308555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 308655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume } 30874c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { 308834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->setTextureUnit(unitIdx); 308910528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS)); 30904c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com } 30914c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { 309234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->setTextureUnit(unitIdx); 309310528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT)); 30944c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com } 3095cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon if (this->glCaps().textureSwizzleSupport() && 30964c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com (setAll || memcmp(newTexParams.fSwizzleRGBA, 30974c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com oldTexParams.fSwizzleRGBA, 30984c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com sizeof(newTexParams.fSwizzleRGBA)))) { 309974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->setTextureSwizzle(unitIdx, target, newTexParams.fSwizzleRGBA); 31004c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com } 310134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); 31024c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com} 31034c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 31041897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdaltonvoid GrGLGpu::bindTexelBuffer(int unitIdx, GrPixelConfig texelConfig, GrGLBuffer* buffer) { 310574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton SkASSERT(this->glCaps().canUseConfigWithTexelBuffer(texelConfig)); 310674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton SkASSERT(unitIdx >= 0 && unitIdx < fHWBufferTextures.count()); 310774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 310874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton BufferTexture& buffTex = fHWBufferTextures[unitIdx]; 310974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 311074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (!buffTex.fKnownBound) { 311174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (!buffTex.fTextureID) { 311274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(GenTextures(1, &buffTex.fTextureID)); 311374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (!buffTex.fTextureID) { 311474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton return; 311574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 311674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 311774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 311874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->setTextureUnit(unitIdx); 311974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID)); 312074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 312174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton buffTex.fKnownBound = true; 312274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 312374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 31248abb370aca280516f4861c6c942ec453aad018farobertphillips if (buffer->uniqueID() != buffTex.fAttachedBufferUniqueID || 31251897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton buffTex.fTexelConfig != texelConfig) { 312674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 312774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->setTextureUnit(unitIdx); 31281897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER, 31291897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton this->glCaps().configSizedInternalFormat(texelConfig), 31301897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton buffer->bufferID())); 313174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 313274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton buffTex.fTexelConfig = texelConfig; 31338abb370aca280516f4861c6c942ec453aad018farobertphillips buffTex.fAttachedBufferUniqueID = buffer->uniqueID(); 313474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 313574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (this->glCaps().textureSwizzleSupport() && 313674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->glCaps().configSwizzle(texelConfig) != buffTex.fSwizzle) { 313774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GrGLenum glSwizzle[4]; 313874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); 313974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); 314074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); 314174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 314274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 314374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton buffer->setHasAttachedToTexture(); 314474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUnit); 314574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 314674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton} 314774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 3148f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomonvoid GrGLGpu::bindImageStorage(int unitIdx, GrIOType ioType, GrGLTexture *texture) { 3149f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon SkASSERT(texture); 3150f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon if (texture->uniqueID() != fHWBoundImageStorages[unitIdx].fTextureUniqueID || 3151f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon ioType != fHWBoundImageStorages[unitIdx].fIOType) { 315294e4ab1e353f2202369798045ec3dfe0a89c9bbeJoe Gregorio GrGLenum access = GR_GL_READ_ONLY; 3153f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon switch (ioType) { 3154f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon case kRead_GrIOType: 3155f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon access = GR_GL_READ_ONLY; 3156f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon break; 3157f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon case kWrite_GrIOType: 3158f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon access = GR_GL_WRITE_ONLY; 3159f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon break; 3160f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon case kRW_GrIOType: 3161f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon access = GR_GL_READ_WRITE; 3162f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon break; 3163f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon } 3164f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GrGLenum format = this->glCaps().getImageFormat(texture->config()); 3165f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GL_CALL(BindImageTexture(unitIdx, texture->textureID(), 0, GR_GL_FALSE, 0, access, format)); 3166f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon } 3167f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon} 3168f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon 3169514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomonvoid GrGLGpu::generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs, 317033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLTexture* texture) { 317133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman SkASSERT(texture); 317233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 317333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // First, figure out if we need mips for this texture at all: 3174514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon GrSamplerParams::FilterMode filterMode = params.filterMode(); 317533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 3176514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon if (GrSamplerParams::kMipMap_FilterMode == filterMode) { 317733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture->config())) { 3178514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon filterMode = GrSamplerParams::kBilerp_FilterMode; 317933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 318033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 318133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 3182514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon if (GrSamplerParams::kMipMap_FilterMode != filterMode) { 318333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return; 318433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 318533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 318633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // If this is an sRGB texture and the mips were previously built the "other" way 318733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // (gamma-correct vs. not), then we need to rebuild them. We don't need to check for 318833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // srgbSupport - we'll *never* get an sRGB pixel config if we don't support it. 31897b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman SkDestinationSurfaceColorMode colorMode = allowSRGBInputs 31907b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware 31917b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman : SkDestinationSurfaceColorMode::kLegacy; 319233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (GrPixelConfigIsSRGB(texture->config()) && 31937b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman colorMode != texture->texturePriv().mipColorMode()) { 319433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman texture->texturePriv().dirtyMipMaps(true); 319533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 319633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 319733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // If the mips aren't dirty, we're done: 319833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!texture->texturePriv().mipMapsAreDirty()) { 319933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return; 320033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 320133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 320233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // If we created a rt/tex and rendered to it without using a texture and now we're texturing 320333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // from the rt it will still be the last bound texture, but it needs resolving. 320433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget()); 320533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (texRT) { 320633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->onResolveRenderTarget(texRT); 320733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 320833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 320933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLenum target = texture->target(); 321033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->setScratchTextureUnit(); 321133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(BindTexture(target, texture->textureID())); 321233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 321333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Configure sRGB decode, if necessary. This state is the only thing needed for the driver 321433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // call (glGenerateMipmap) to work correctly. Our manual method dirties other state, too. 321520471894eaa441193d5ae8f2395e8244c91c55afbrianosman if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) { 3216b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman GrGLenum srgbDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT; 3217b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman // Command buffer's sRGB decode extension doesn't influence mipmap generation correctly. 3218b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman // If we set this to skip_decode, it appears to suppress sRGB -> Linear for each downsample, 3219b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman // but not the Linear -> sRGB when writing the next level. The result is that mip-chains 3220b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman // get progressively brighter as you go down. Forcing this to 'decode' gives predictable 3221b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman // (and only slightly incorrect) results. See crbug.com/655247 (~comment 28) 3222b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman if (!this->glCaps().srgbDecodeDisableAffectsMipmaps()) { 3223b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman srgbDecode = GR_GL_DECODE_EXT; 3224b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman } 3225b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, srgbDecode)); 322633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 322733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 322833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Either do manual mipmap generation or (if that fails), just rely on the driver: 322933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!this->generateMipmap(texture, allowSRGBInputs)) { 323033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(GenerateMipmap(target)); 323133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 323233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 3233fe19987e5499650e8637a8d109f19b8156601660brianosman texture->texturePriv().dirtyMipMaps(false); 323433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount( 323533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman texture->width(), texture->height())); 32367b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman texture->texturePriv().setMipColorMode(colorMode); 323733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 323833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // We have potentially set lots of state on the texture. Easiest to dirty it all: 323933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman texture->textureParamsModified(); 324033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman} 324133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 324274b8d323323c8533e3e5cc7719e0bd127aacd829cdaltonvoid GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]) { 324374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton this->setTextureUnit(unitIdx); 324474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton if (this->glStandard() == kGLES_GrGLStandard) { 324574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. 324674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); 324774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); 324874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); 324974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); 325074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } else { 325174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); 325274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA, 325374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton reinterpret_cast<const GrGLint*>(swizzle))); 325474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton } 325574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton} 325674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton 3257080e673b10ac607305f140ddb245e140ccde40c6egdanielvoid GrGLGpu::flushColorWrite(bool writeColor) { 3258080e673b10ac607305f140ddb245e140ccde40c6egdaniel if (!writeColor) { 3259978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com if (kNo_TriState != fHWWriteToColor) { 3260978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE, 3261978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com GR_GL_FALSE, GR_GL_FALSE)); 3262978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com fHWWriteToColor = kNo_TriState; 3263978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com } 3264978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com } else { 3265978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com if (kYes_TriState != fHWWriteToColor) { 3266978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); 3267978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com fHWWriteToColor = kYes_TriState; 3268d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com } 3269d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com } 32703e79124a69d4806f0a1a776090bff718e1b90970bsalomon} 3271d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 32725fa7f30331585f78cf0f81ac185abbff1fee1152robertphillipsvoid GrGLGpu::flushDrawFace(GrDrawFace face) { 32733e79124a69d4806f0a1a776090bff718e1b90970bsalomon if (fHWDrawFace != face) { 32743e79124a69d4806f0a1a776090bff718e1b90970bsalomon switch (face) { 32755fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips case GrDrawFace::kCCW: 32760b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(Enable(GR_GL_CULL_FACE)); 32770b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(CullFace(GR_GL_BACK)); 3278d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com break; 32795fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips case GrDrawFace::kCW: 32800b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(Enable(GR_GL_CULL_FACE)); 32810b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(CullFace(GR_GL_FRONT)); 3282d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com break; 32835fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips case GrDrawFace::kBoth: 32840b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(Disable(GR_GL_CULL_FACE)); 3285d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com break; 3286d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com default: 328788cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown draw face."); 3288d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com } 32893e79124a69d4806f0a1a776090bff718e1b90970bsalomon fHWDrawFace = face; 3290d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com } 3291ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 3292ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3293861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::setTextureUnit(int unit) { 32941c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon SkASSERT(unit >= 0 && unit < fHWBoundTextureUniqueIDs.count()); 3295a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org if (unit != fHWActiveTextureUnitIdx) { 32960b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit)); 3297492093951ae2a7d7c14aa22f48faa8942f045cafbsalomon@google.com fHWActiveTextureUnitIdx = unit; 32988531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com } 32998531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com} 3300316f9923cb265cea8d52aafeb28f959870124207bsalomon@google.com 3301861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::setScratchTextureUnit() { 3302a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org // Bind the last texture unit since it is the least likely to be used by GrGLProgram. 33031c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1; 3304a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org if (lastUnitIdx != fHWActiveTextureUnitIdx) { 3305a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx)); 3306a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org fHWActiveTextureUnitIdx = lastUnitIdx; 33078531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com } 3308a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org // clear out the this field so that if a program does use this unit it will rebind the correct 3309a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org // texture. 3310294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundTextureUniqueIDs[lastUnitIdx].makeInvalid(); 33118531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com} 33128531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com 3313e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon// Determines whether glBlitFramebuffer could be used between src and dst by onCopySurface. 3314e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomonstatic inline bool can_blit_framebuffer_for_copy_surface(const GrSurface* dst, 3315e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const GrSurface* src, 3316e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const SkIRect& srcRect, 3317e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const SkIPoint& dstPoint, 3318e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const GrGLGpu* gpu) { 3319e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon auto blitFramebufferFlags = gpu->glCaps().blitFramebufferSupportFlags(); 332071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (!gpu->glCaps().canConfigBeFBOColorAttachment(dst->config()) || 332171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon !gpu->glCaps().canConfigBeFBOColorAttachment(src->config())) { 3322e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3323e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3324bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon // Blits are not allowed between int color buffers and float/fixed color buffers. GrGpu should 3325bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon // have filtered such cases out. 3326bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon SkASSERT(GrPixelConfigIsSint(dst->config()) == GrPixelConfigIsSint(src->config())); 3327e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture()); 3328e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(dst->asTexture()); 3329e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const GrRenderTarget* dstRT = dst->asRenderTarget(); 3330e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const GrRenderTarget* srcRT = src->asRenderTarget(); 3331e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (dstTex && dstTex->target() != GR_GL_TEXTURE_2D) { 3332e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3333e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3334e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (srcTex && srcTex->target() != GR_GL_TEXTURE_2D) { 3335e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3336e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3337e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) { 3338e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3339e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3340e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) { 3341e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon // We would mirror to compensate for origin changes. Note that copySurface is 3342e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon // specified such that the src and dst rects are the same. 3343e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (dst->origin() != src->origin()) { 3344e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3345a8e5a06f69b7e0cb17a4b3203f0a7a1d52aa73eccommit-bot@chromium.org } 3346e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3347e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) { 3348e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (srcRT && srcRT->numColorSamples() && dstRT && !dstRT->numColorSamples()) { 33497ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon return false; 33507ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 3351e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3352e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) { 3353e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (dstRT && dstRT->numColorSamples() > 0) { 3354e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3355e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3356e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3357e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) { 3358e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (dst->config() != src->config()) { 3359e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3360e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3361e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) { 3362e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon const GrRenderTarget* srcRT = src->asRenderTarget(); 3363e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (srcRT && srcRT->numColorSamples() && dst->config() != src->config()) { 33647ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon return false; 33657ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 3366eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } 3367e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) { 3368e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (srcRT && srcRT->numColorSamples() && 3369e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop)) { 3370e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return false; 3371e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3372e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon } 3373e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon return true; 337463150afcc0c4120370db6f5566cd404584345668commit-bot@chromium.org} 3375eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com 33767ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomonstatic inline bool can_copy_texsubimage(const GrSurface* dst, 33777ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon const GrSurface* src, 33787ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon const GrGLGpu* gpu) { 3379eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage 3380eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps 3381eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com // many drivers would allow it to work, but ANGLE does not. 33829e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalFormat() && 3383eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig == src->config())) { 3384eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com return false; 3385eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } 3386eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget()); 3387eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer) 3388eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com // then we don't want to copy to the texture but to the MSAA buffer. 3389d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { 3390eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com return false; 3391eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } 3392a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget()); 3393a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com // If the src is multisampled (and uses an extension where there is a separate MSAA 3394a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com // renderbuffer) then it is an invalid operation to call CopyTexSubImage 3395d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { 3396a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com return false; 3397a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com } 33987ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon 33997ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture()); 34007ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a 34017ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon // texture. 34027ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon if (!dstTex) { 34037ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon return false; 34047ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 34057ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon 34067ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture()); 34076121405df5689875c7309c20632a82897fce4127cblume 34087ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring 34097ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon // is required. 341071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (gpu->glCaps().canConfigBeFBOColorAttachment(src->config()) && 34117ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon !GrPixelConfigIsCompressed(src->config()) && 341271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon (!srcTex || srcTex->target() == GR_GL_TEXTURE_2D) && dstTex->target() == GR_GL_TEXTURE_2D && 34137ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon dst->origin() == src->origin()) { 3414eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com return true; 3415eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } else { 3416eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com return false; 3417eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } 3418eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com} 3419eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com 3420eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is 3421eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com// relative to is output. 342271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomonvoid GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport, 342371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon TempFBOTarget tempFBOTarget) { 3424eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget()); 3425083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon if (!rt) { 342649f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(surface->asTexture()); 3427eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID(); 342810528f1d5838ae1cac015024c4e8731484f888d1bsalomon GrGLenum target = static_cast<GrGLTexture*>(surface->asTexture())->target(); 3429d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GrGLuint* tempFBOID; 3430d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTempDstFBOID; 34310f5f967f6777612353c762e6d0095f733adfb326egdaniel 3432d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel if (0 == *tempFBOID) { 3433d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID)); 34340f5f967f6777612353c762e6d0095f733adfb326egdaniel } 34350f5f967f6777612353c762e6d0095f733adfb326egdaniel 3436d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fStats.incRenderTargetBinds(); 3437d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID)); 3438d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, 3439754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_COLOR_ATTACHMENT0, 344010528f1d5838ae1cac015024c4e8731484f888d1bsalomon target, 3441754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips texID, 3442754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips 0)); 3443eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com viewport->fLeft = 0; 3444eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com viewport->fBottom = 0; 3445eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com viewport->fWidth = surface->width(); 3446eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com viewport->fHeight = surface->height(); 3447eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } else { 3448d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel fStats.incRenderTargetBinds(); 3449d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID())); 3450eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com *viewport = rt->getViewport(); 3451eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } 34520f5f967f6777612353c762e6d0095f733adfb326egdaniel} 34530f5f967f6777612353c762e6d0095f733adfb326egdaniel 345471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomonvoid GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface) { 345571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon // bindSurfaceFBOForPixelOps temporarily binds textures that are not render targets to 345610528f1d5838ae1cac015024c4e8731484f888d1bsalomon if (!surface->asRenderTarget()) { 345710528f1d5838ae1cac015024c4e8731484f888d1bsalomon SkASSERT(surface->asTexture()); 345810528f1d5838ae1cac015024c4e8731484f888d1bsalomon GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())->target(); 345910528f1d5838ae1cac015024c4e8731484f888d1bsalomon GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, 346010528f1d5838ae1cac015024c4e8731484f888d1bsalomon GR_GL_COLOR_ATTACHMENT0, 346110528f1d5838ae1cac015024c4e8731484f888d1bsalomon textureTarget, 346210528f1d5838ae1cac015024c4e8731484f888d1bsalomon 0, 346310528f1d5838ae1cac015024c4e8731484f888d1bsalomon 0)); 346410528f1d5838ae1cac015024c4e8731484f888d1bsalomon } 3465eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com} 3466eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com 34671cbdcde9116e9efb514236faf8cfa42649a041d1joshualittbool GrGLGpu::onCopySurface(GrSurface* dst, 34681cbdcde9116e9efb514236faf8cfa42649a041d1joshualitt GrSurface* src, 34691cbdcde9116e9efb514236faf8cfa42649a041d1joshualitt const SkIRect& srcRect, 34701cbdcde9116e9efb514236faf8cfa42649a041d1joshualitt const SkIPoint& dstPoint) { 34717f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the 34727f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon // swizzle. 34731edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (this->caps()->shaderCaps()->configOutputSwizzle(src->config()) != 34741edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon this->caps()->shaderCaps()->configOutputSwizzle(dst->config())) { 34757f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon return false; 34767f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon } 3477083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon // Don't prefer copying as a draw if the dst doesn't already have a FBO object. 3478083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon bool preferCopy = SkToBool(dst->asRenderTarget()); 3479083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon if (preferCopy && src->asTexture()) { 3480e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) { 3481e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return true; 3482e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 348363150afcc0c4120370db6f5566cd404584345668commit-bot@chromium.org } 34846121405df5689875c7309c20632a82897fce4127cblume 34850f5f967f6777612353c762e6d0095f733adfb326egdaniel if (can_copy_texsubimage(dst, src, this)) { 34866df86409ca586c3cb34f616f03501bd96181f9e4bsalomon this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); 3487eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com return true; 3488eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com } 34896df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 3490e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon if (can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this)) { 34916df86409ca586c3cb34f616f03501bd96181f9e4bsalomon return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); 34925df6fee929823f50c55cc50f7c882a309c1b1de9bsalomon } 34936df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 3494083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon if (!preferCopy && src->asTexture()) { 3495e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) { 3496e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return true; 3497e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3498083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon } 3499083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon 3500404b3b264b833eb7cffdc833c7e2ebbd708e123amtklein return false; 35015df6fee929823f50c55cc50f7c882a309c1b1de9bsalomon} 35025df6fee929823f50c55cc50f7c882a309c1b1de9bsalomon 3503bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomonbool GrGLGpu::createCopyProgram(GrTexture* srcTex) { 3504bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon int progIdx = TextureToCopyProgramIdx(srcTex); 35051edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon const GrShaderCaps* shaderCaps = this->caps()->shaderCaps(); 3506bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon GrSLType samplerType = srcTex->texturePriv().samplerType(); 3507e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3508e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fCopyProgramArrayBuffer) { 3509e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton static const GrGLfloat vdata[] = { 3510e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 0, 0, 3511e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 0, 1, 3512e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 1, 0, 3513e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 1, 1 3514e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton }; 3515e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fCopyProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType, 3516e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton kStatic_GrAccessPattern, vdata)); 3517e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3518e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fCopyProgramArrayBuffer) { 3519e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return false; 3520e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3521e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3522e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton SkASSERT(!fCopyPrograms[progIdx].fProgram); 3523e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL_RET(fCopyPrograms[progIdx].fProgram, CreateProgram()); 3524e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fCopyPrograms[progIdx].fProgram) { 3525e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return false; 3526e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3527e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 35281edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon const char* version = shaderCaps->versionDeclString(); 352999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier); 353099938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, 353199938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar::kUniform_TypeModifier); 353299938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier); 353399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar uTexture("u_texture", samplerType, GrShaderVar::kUniform_TypeModifier); 353499938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier); 353599938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier); 3536deacc97bc63513b5eacaf21f858727f6e8b98ce5cdalton 3537e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton SkString vshaderTxt(version); 35381edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (shaderCaps->noperspectiveInterpolationSupport()) { 35391edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 3540e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vshaderTxt.appendf("#extension %s : require\n", extension); 35417ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon } 3542e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vTexCoord.addModifier("noperspective"); 3543e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3544e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 35451edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon aVertex.appendDecl(shaderCaps, &vshaderTxt); 3546e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vshaderTxt.append(";"); 35471edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt); 3548e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vshaderTxt.append(";"); 35491edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon uPosXform.appendDecl(shaderCaps, &vshaderTxt); 3550e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vshaderTxt.append(";"); 35511edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon vTexCoord.appendDecl(shaderCaps, &vshaderTxt); 3552e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vshaderTxt.append(";"); 3553e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3554e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton vshaderTxt.append( 3555e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton "// Copy Program VS\n" 3556e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton "void main() {" 3557e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" 3558e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" 3559e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton " gl_Position.zw = vec2(0, 1);" 3560e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton "}" 3561e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton ); 3562e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3563e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton SkString fshaderTxt(version); 35641edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (shaderCaps->noperspectiveInterpolationSupport()) { 35651edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 3566e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fshaderTxt.appendf("#extension %s : require\n", extension); 3567044d3c185876f9960f07b88f068cf08d78311e33mtklein } 3568e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3569bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon if (samplerType == kTextureExternalSampler_GrSLType) { 3570e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fshaderTxt.appendf("#extension %s : require\n", 35711edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon shaderCaps->externalTextureExtensionString()); 3572e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 35731edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps, 3574e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton &fshaderTxt); 3575f31ae495271e0343f568fb9a1d7e2df81e196896Brian Salomon vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier); 35761edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon vTexCoord.appendDecl(shaderCaps, &fshaderTxt); 3577e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fshaderTxt.append(";"); 35781edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon uTexture.appendDecl(shaderCaps, &fshaderTxt); 3579e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fshaderTxt.append(";"); 3580e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fshaderTxt.appendf( 3581e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton "// Copy Program FS\n" 3582e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton "void main() {" 35832b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " sk_FragColor = texture(u_texture, v_texCoord);" 35842b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas "}" 3585e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton ); 3586e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3587e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton const char* str; 3588e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GrGLint length; 3589e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3590e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton str = vshaderTxt.c_str(); 3591e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton length = SkToInt(vshaderTxt.size()); 3592941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkSL::Program::Settings settings; 3593941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas settings.fCaps = shaderCaps; 3594941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkSL::Program::Inputs inputs; 3595e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram, 3596e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GR_GL_VERTEX_SHADER, &str, &length, 1, 3597941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas &fStats, settings, &inputs); 3598941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkASSERT(inputs.isEmpty()); 3599e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3600e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton str = fshaderTxt.c_str(); 3601e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton length = SkToInt(fshaderTxt.size()); 3602e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram, 3603e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GR_GL_FRAGMENT_SHADER, &str, &length, 1, 3604941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas &fStats, settings, &inputs); 3605941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkASSERT(inputs.isEmpty()); 3606e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3607e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL(LinkProgram(fCopyPrograms[progIdx].fProgram)); 3608e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3609e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL_RET(fCopyPrograms[progIdx].fTextureUniform, 3610e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texture")); 3611e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL_RET(fCopyPrograms[progIdx].fPosXformUniform, 3612e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_posXform")); 3613e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL_RET(fCopyPrograms[progIdx].fTexCoordXformUniform, 3614e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordXform")); 3615e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3616e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex")); 3617e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3618e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL(DeleteShader(vshader)); 3619e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL(DeleteShader(fshader)); 3620e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3621e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return true; 3622044d3c185876f9960f07b88f068cf08d78311e33mtklein} 3623deacc97bc63513b5eacaf21f858727f6e8b98ce5cdalton 362433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosmanbool GrGLGpu::createMipmapProgram(int progIdx) { 362533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman const bool oddWidth = SkToBool(progIdx & 0x2); 362633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman const bool oddHeight = SkToBool(progIdx & 0x1); 362733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman const int numTaps = (oddWidth ? 2 : 1) * (oddHeight ? 2 : 1); 362833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 36291edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon const GrShaderCaps* shaderCaps = this->caps()->shaderCaps(); 363033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 363133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman SkASSERT(!fMipmapPrograms[progIdx].fProgram); 363233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL_RET(fMipmapPrograms[progIdx].fProgram, CreateProgram()); 363333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!fMipmapPrograms[progIdx].fProgram) { 363433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 363533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 363633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 36371edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon const char* version = shaderCaps->versionDeclString(); 363899938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier); 363999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, 364099938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar::kUniform_TypeModifier); 364199938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar uTexture("u_texture", kTexture2DSampler_GrSLType, 364299938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar::kUniform_TypeModifier); 364333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // We need 1, 2, or 4 texture coordinates (depending on parity of each dimension): 364499938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar vTexCoords[] = { 364599938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar("v_texCoord0", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier), 364699938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar("v_texCoord1", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier), 364799938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar("v_texCoord2", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier), 364899938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar("v_texCoord3", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier), 364933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman }; 365099938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType,GrShaderVar::kOut_TypeModifier); 365133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 365233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman SkString vshaderTxt(version); 36531edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (shaderCaps->noperspectiveInterpolationSupport()) { 36541edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 365533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.appendf("#extension %s : require\n", extension); 365633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 365733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vTexCoords[0].addModifier("noperspective"); 365833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vTexCoords[1].addModifier("noperspective"); 365933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vTexCoords[2].addModifier("noperspective"); 366033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vTexCoords[3].addModifier("noperspective"); 366133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 366233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 36631edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon aVertex.appendDecl(shaderCaps, &vshaderTxt); 366433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append(";"); 36651edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt); 366633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append(";"); 366733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (int i = 0; i < numTaps; ++i) { 36681edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon vTexCoords[i].appendDecl(shaderCaps, &vshaderTxt); 366933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append(";"); 367033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 367133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 367233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append( 367333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman "// Mipmap Program VS\n" 367433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman "void main() {" 367533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " gl_Position.xy = a_vertex * vec2(2, 2) - vec2(1, 1);" 367633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " gl_Position.zw = vec2(0, 1);" 367733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 367833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 367933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Insert texture coordinate computation: 368033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (oddWidth && oddHeight) { 368133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append( 368233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord0 = a_vertex.xy * u_texCoordXform.yw;" 368333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord1 = a_vertex.xy * u_texCoordXform.yw + vec2(u_texCoordXform.x, 0);" 368433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord2 = a_vertex.xy * u_texCoordXform.yw + vec2(0, u_texCoordXform.z);" 368533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord3 = a_vertex.xy * u_texCoordXform.yw + u_texCoordXform.xz;" 368633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 368733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } else if (oddWidth) { 368833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append( 368933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord0 = a_vertex.xy * vec2(u_texCoordXform.y, 1);" 369033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord1 = a_vertex.xy * vec2(u_texCoordXform.y, 1) + vec2(u_texCoordXform.x, 0);" 369133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 369233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } else if (oddHeight) { 369333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append( 369433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord0 = a_vertex.xy * vec2(1, u_texCoordXform.w);" 369533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord1 = a_vertex.xy * vec2(1, u_texCoordXform.w) + vec2(0, u_texCoordXform.z);" 369633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 369733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } else { 369833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append( 369933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman " v_texCoord0 = a_vertex.xy;" 370033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 370133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 370233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 370333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman vshaderTxt.append("}"); 370433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 370533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman SkString fshaderTxt(version); 37061edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (shaderCaps->noperspectiveInterpolationSupport()) { 37071edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) { 370833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fshaderTxt.appendf("#extension %s : require\n", extension); 370933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 371033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 37111edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps, 371233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman &fshaderTxt); 371333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (int i = 0; i < numTaps; ++i) { 3714f31ae495271e0343f568fb9a1d7e2df81e196896Brian Salomon vTexCoords[i].setTypeModifier(GrShaderVar::kIn_TypeModifier); 37151edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon vTexCoords[i].appendDecl(shaderCaps, &fshaderTxt); 371633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fshaderTxt.append(";"); 371733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 37181edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon uTexture.appendDecl(shaderCaps, &fshaderTxt); 371933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fshaderTxt.append(";"); 372033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fshaderTxt.append( 372133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman "// Mipmap Program FS\n" 372233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman "void main() {" 372333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 372433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 372533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (oddWidth && oddHeight) { 37262b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas fshaderTxt.append( 37272b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " sk_FragColor = (texture(u_texture, v_texCoord0) + " 37282b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " texture(u_texture, v_texCoord1) + " 37292b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " texture(u_texture, v_texCoord2) + " 37302b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " texture(u_texture, v_texCoord3)) * 0.25;" 373133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 373233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } else if (oddWidth || oddHeight) { 37332b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas fshaderTxt.append( 37342b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " sk_FragColor = (texture(u_texture, v_texCoord0) + " 37352b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " texture(u_texture, v_texCoord1)) * 0.5;" 373633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 373733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } else { 37382b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas fshaderTxt.append( 37392b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas " sk_FragColor = texture(u_texture, v_texCoord0);" 374033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman ); 374133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 374233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 374333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fshaderTxt.append("}"); 374433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 374533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman const char* str; 374633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLint length; 374733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 374833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman str = vshaderTxt.c_str(); 374933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman length = SkToInt(vshaderTxt.size()); 3750941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkSL::Program::Settings settings; 3751941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas settings.fCaps = shaderCaps; 3752941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkSL::Program::Inputs inputs; 375333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram, 375433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GR_GL_VERTEX_SHADER, &str, &length, 1, 3755941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas &fStats, settings, &inputs); 3756941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkASSERT(inputs.isEmpty()); 375733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 375833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman str = fshaderTxt.c_str(); 375933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman length = SkToInt(fshaderTxt.size()); 376033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram, 376133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GR_GL_FRAGMENT_SHADER, &str, &length, 1, 3762941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas &fStats, settings, &inputs); 3763941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkASSERT(inputs.isEmpty()); 376433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 376533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(LinkProgram(fMipmapPrograms[progIdx].fProgram)); 376633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 376733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL_RET(fMipmapPrograms[progIdx].fTextureUniform, 376833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texture")); 376933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL_RET(fMipmapPrograms[progIdx].fTexCoordXformUniform, 377033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texCoordXform")); 377133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 377233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(BindAttribLocation(fMipmapPrograms[progIdx].fProgram, 0, "a_vertex")); 377333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 377433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(DeleteShader(vshader)); 377533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(DeleteShader(fshader)); 377633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 377733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return true; 377833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman} 377933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 3780e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonbool GrGLGpu::createWireRectProgram() { 3781e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fWireRectArrayBuffer) { 3782e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton static const GrGLfloat vdata[] = { 3783e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 0, 0, 3784e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 0, 1, 3785e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 1, 1, 3786e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 1, 0 3787e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton }; 3788e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fWireRectArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType, 3789e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton kStatic_GrAccessPattern, vdata)); 3790e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fWireRectArrayBuffer) { 3791e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return false; 3792e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3793e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3794e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 37956dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon SkASSERT(!fWireRectProgram.fProgram); 3796e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GL_CALL_RET(fWireRectProgram.fProgram, CreateProgram()); 3797e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fWireRectProgram.fProgram) { 3798e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return false; 3799e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3800e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 380199938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar uColor("u_color", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier); 380299938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar uRect("u_rect", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier); 380399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier); 38041edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon const char* version = this->caps()->shaderCaps()->versionDeclString(); 38056dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38066dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon // The rect uniform specifies the rectangle in NDC space as a vec4 (left,top,right,bottom). The 38076dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon // program is used with a vbo containing the unit square. Vertices are computed from the rect 38086dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon // uniform using the 4 vbo vertices. 38096dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon SkString vshaderTxt(version); 38101edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon aVertex.appendDecl(this->caps()->shaderCaps(), &vshaderTxt); 38116dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon vshaderTxt.append(";"); 38121edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon uRect.appendDecl(this->caps()->shaderCaps(), &vshaderTxt); 38136dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon vshaderTxt.append(";"); 38146dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon vshaderTxt.append( 38156dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon "// Wire Rect Program VS\n" 38166dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon "void main() {" 38176dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon " gl_Position.x = u_rect.x + a_vertex.x * (u_rect.z - u_rect.x);" 38186dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon " gl_Position.y = u_rect.y + a_vertex.y * (u_rect.w - u_rect.y);" 38196dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon " gl_Position.zw = vec2(0, 1);" 38206dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon "}" 38216dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon ); 38226dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 382399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier); 38246dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38256dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon SkString fshaderTxt(version); 38266dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, 38271edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon *this->caps()->shaderCaps(), 38286dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon &fshaderTxt); 38291edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon uColor.appendDecl(this->caps()->shaderCaps(), &fshaderTxt); 38306dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon fshaderTxt.append(";"); 38316dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon fshaderTxt.appendf( 38326dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon "// Write Rect Program FS\n" 38336dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon "void main() {" 38345961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas " sk_FragColor = %s;" 38356dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon "}", 38366dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon uColor.c_str() 38376dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon ); 38386dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38396dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon const char* str; 38406dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrGLint length; 38416dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38426dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon str = vshaderTxt.c_str(); 38436dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon length = SkToInt(vshaderTxt.size()); 3844941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkSL::Program::Settings settings; 3845941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas settings.fCaps = this->caps()->shaderCaps(); 3846941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkSL::Program::Inputs inputs; 38476dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram, 38486dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GR_GL_VERTEX_SHADER, &str, &length, 1, 3849941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas &fStats, settings, &inputs); 3850941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkASSERT(inputs.isEmpty()); 38516dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38526dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon str = fshaderTxt.c_str(); 38536dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon length = SkToInt(fshaderTxt.size()); 38546dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram, 38556dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GR_GL_FRAGMENT_SHADER, &str, &length, 1, 3856941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas &fStats, settings, &inputs); 3857941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas SkASSERT(inputs.isEmpty()); 38586dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38596dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(LinkProgram(fWireRectProgram.fProgram)); 38606dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38616dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL_RET(fWireRectProgram.fColorUniform, 38626dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GetUniformLocation(fWireRectProgram.fProgram, "u_color")); 38636dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL_RET(fWireRectProgram.fRectUniform, 38646dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GetUniformLocation(fWireRectProgram.fProgram, "u_rect")); 38656dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(BindAttribLocation(fWireRectProgram.fProgram, 0, "a_vertex")); 38666dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38676dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(DeleteShader(vshader)); 38686dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(DeleteShader(fshader)); 3869e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3870e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return true; 38716dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon} 38726dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38736dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomonvoid GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) { 38747f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon // TODO: This should swizzle the output to match dst's config, though it is a debugging 38757f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon // visualization. 38767f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon 38776dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon this->handleDirtyContext(); 38786dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon if (!fWireRectProgram.fProgram) { 3879e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!this->createWireRectProgram()) { 3880e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton SkDebugf("Failed to create wire rect program.\n"); 3881e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return; 3882e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 38836dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon } 38846dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38856dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon int w = rt->width(); 38866dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon int h = rt->height(); 38876dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 38886dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon // Compute the edges of the rectangle (top,left,right,bottom) in NDC space. Must consider 38896dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon // whether the render target is flipped or not. 38906dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrGLfloat edges[4]; 38916dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[0] = SkIntToScalar(rect.fLeft) + 0.5f; 38926dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[2] = SkIntToScalar(rect.fRight) - 0.5f; 38936dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { 38946dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[1] = h - (SkIntToScalar(rect.fTop) + 0.5f); 38956dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[3] = h - (SkIntToScalar(rect.fBottom) - 0.5f); 38966dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon } else { 38976dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[1] = SkIntToScalar(rect.fTop) + 0.5f; 38986dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[3] = SkIntToScalar(rect.fBottom) - 0.5f; 38996dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon } 39006dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[0] = 2 * edges[0] / w - 1.0f; 39016dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[1] = 2 * edges[1] / h - 1.0f; 39026dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[2] = 2 * edges[2] / w - 1.0f; 39036dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon edges[3] = 2 * edges[3] / h - 1.0f; 39046dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 39056dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrGLfloat channels[4]; 39066dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon static const GrGLfloat scale255 = 1.f / 255.f; 39076dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon channels[0] = GrColorUnpackR(color) * scale255; 39086dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon channels[1] = GrColorUnpackG(color) * scale255; 39096dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon channels[2] = GrColorUnpackB(color) * scale255; 39106dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon channels[3] = GrColorUnpackA(color) * scale255; 39116dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 39126dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget()); 39136dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon this->flushRenderTarget(glRT, &rect); 39146dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 39156dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(UseProgram(fWireRectProgram.fProgram)); 39166dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon fHWProgramID = fWireRectProgram.fProgram; 39176dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 3918e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWVertexArrayState.setVertexArrayID(this, 0); 39196dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 3920e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); 3921144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary attribs->set(this, 0, fWireRectArrayBuffer.get(), kVec2f_GrVertexAttribType, 3922144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary 2 * sizeof(GrGLfloat), 0); 39236dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon attribs->disableUnusedArrays(this, 0x1); 39246dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 39256dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(Uniform4fv(fWireRectProgram.fRectUniform, 1, edges)); 39266dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(Uniform4fv(fWireRectProgram.fColorUniform, 1, channels)); 39276dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 39286dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GrXferProcessor::BlendInfo blendInfo; 39296dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon blendInfo.reset(); 39307f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon this->flushBlend(blendInfo, GrSwizzle::RGBA()); 39316dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon this->flushColorWrite(true); 39325fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips this->flushDrawFace(GrDrawFace::kBoth); 3933af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton this->flushHWAAState(glRT, false, false); 39346dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon this->disableScissor(); 393528341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton this->disableWindowRectangles(); 3936c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton this->disableStencil(); 39376dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 39386dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon GL_CALL(DrawArrays(GR_GL_LINE_LOOP, 0, 4)); 39396dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon} 39406dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 39416dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon 3942e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonbool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, 39436df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrSurface* src, 39446df86409ca586c3cb34f616f03501bd96181f9e4bsalomon const SkIRect& srcRect, 39456df86409ca586c3cb34f616f03501bd96181f9e4bsalomon const SkIPoint& dstPoint) { 3946e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture()); 3947bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon int progIdx = TextureToCopyProgramIdx(srcTex); 3948e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 3949e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fCopyPrograms[progIdx].fProgram) { 3950bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon if (!this->createCopyProgram(srcTex)) { 3951e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton SkDebugf("Failed to create copy program.\n"); 3952e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return false; 3953e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3954e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton } 3955e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton 39566df86409ca586c3cb34f616f03501bd96181f9e4bsalomon int w = srcRect.width(); 39576df86409ca586c3cb34f616f03501bd96181f9e4bsalomon int h = srcRect.height(); 39586df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 3959514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode); 3960a6359365887048ef055196de75591311d7a015f0brianosman this->bindTexture(0, params, true, srcTex); 39616df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 3962083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon GrGLIRect dstVP; 396371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget); 3964083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon this->flushViewport(dstVP); 3965294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 3966083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon 39676df86409ca586c3cb34f616f03501bd96181f9e4bsalomon SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h); 39686df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 39697ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram)); 39707ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon fHWProgramID = fCopyPrograms[progIdx].fProgram; 39716df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 3972e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fHWVertexArrayState.setVertexArrayID(this, 0); 39736df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 3974e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); 3975144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kVec2f_GrVertexAttribType, 3976144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary 2 * sizeof(GrGLfloat), 0); 3977d624634aff330485dc56fc09773cc6d4ec092c4dbsalomon attribs->disableUnusedArrays(this, 0x1); 39786df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 39796df86409ca586c3cb34f616f03501bd96181f9e4bsalomon // dst rect edges in NDC (-1 to 1) 39806df86409ca586c3cb34f616f03501bd96181f9e4bsalomon int dw = dst->width(); 39816df86409ca586c3cb34f616f03501bd96181f9e4bsalomon int dh = dst->height(); 39826df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f; 39836df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f; 39846df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f; 39856df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f; 39866df86409ca586c3cb34f616f03501bd96181f9e4bsalomon if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { 39876df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dy0 = -dy0; 39886df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dy1 = -dy1; 39896df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 39906df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 3991e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft; 3992e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w); 3993e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon GrGLfloat sy0 = (GrGLfloat)srcRect.fTop; 3994e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h); 39956df86409ca586c3cb34f616f03501bd96181f9e4bsalomon int sh = src->height(); 39966df86409ca586c3cb34f616f03501bd96181f9e4bsalomon if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 3997e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon sy0 = sh - sy0; 3998e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon sy1 = sh - sy1; 3999e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon } 4000e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon // src rect edges in normalized texture space (0 to 1) unless we're using a RECTANGLE texture. 4001e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon GrGLenum srcTarget = srcTex->target(); 4002e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon if (GR_GL_TEXTURE_RECTANGLE != srcTarget) { 4003e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon int sw = src->width(); 4004e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon sx0 /= sw; 4005e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon sx1 /= sw; 4006e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon sy0 /= sh; 4007e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon sy1 /= sh; 40086df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 40096df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 40107ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0)); 40117ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform, 40127ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon sx1 - sx0, sy1 - sy0, sx0, sy0)); 40137ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0)); 40146df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 40156df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrXferProcessor::BlendInfo blendInfo; 40166df86409ca586c3cb34f616f03501bd96181f9e4bsalomon blendInfo.reset(); 40177f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon this->flushBlend(blendInfo, GrSwizzle::RGBA()); 40186df86409ca586c3cb34f616f03501bd96181f9e4bsalomon this->flushColorWrite(true); 40195fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips this->flushDrawFace(GrDrawFace::kBoth); 4020083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon this->flushHWAAState(nullptr, false, false); 40216df86409ca586c3cb34f616f03501bd96181f9e4bsalomon this->disableScissor(); 402228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton this->disableWindowRectangles(); 4023c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton this->disableStencil(); 40246df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 40256df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); 402671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst); 4027083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon this->didWriteToSurface(dst, &dstRect); 4028083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon 4029e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton return true; 40306df86409ca586c3cb34f616f03501bd96181f9e4bsalomon} 40316df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 40326df86409ca586c3cb34f616f03501bd96181f9e4bsalomonvoid GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, 40336df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrSurface* src, 40346df86409ca586c3cb34f616f03501bd96181f9e4bsalomon const SkIRect& srcRect, 40356df86409ca586c3cb34f616f03501bd96181f9e4bsalomon const SkIPoint& dstPoint) { 40366df86409ca586c3cb34f616f03501bd96181f9e4bsalomon SkASSERT(can_copy_texsubimage(dst, src, this)); 40376df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLIRect srcVP; 403871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget); 4039083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture()); 40406df86409ca586c3cb34f616f03501bd96181f9e4bsalomon SkASSERT(dstTex); 40416df86409ca586c3cb34f616f03501bd96181f9e4bsalomon // We modified the bound FBO 4042294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 40436df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLIRect srcGLRect; 40446df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcGLRect.setRelativeTo(srcVP, 40456df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.fLeft, 40466df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.fTop, 40476df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.width(), 40486df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.height(), 40496df86409ca586c3cb34f616f03501bd96181f9e4bsalomon src->origin()); 40506df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 40516df86409ca586c3cb34f616f03501bd96181f9e4bsalomon this->setScratchTextureUnit(); 405210528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(BindTexture(dstTex->target(), dstTex->textureID())); 40536df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLint dstY; 40546df86409ca586c3cb34f616f03501bd96181f9e4bsalomon if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { 40556df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); 40566df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } else { 40576df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstY = dstPoint.fY; 40586df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 405910528f1d5838ae1cac015024c4e8731484f888d1bsalomon GL_CALL(CopyTexSubImage2D(dstTex->target(), 0, 4060083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon dstPoint.fX, dstY, 4061083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon srcGLRect.fLeft, srcGLRect.fBottom, 4062083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon srcGLRect.fWidth, srcGLRect.fHeight)); 406371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, src); 4064083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 4065083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon srcRect.width(), srcRect.height()); 4066083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon this->didWriteToSurface(dst, &dstRect); 40676df86409ca586c3cb34f616f03501bd96181f9e4bsalomon} 40686df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 40696df86409ca586c3cb34f616f03501bd96181f9e4bsalomonbool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, 40706df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrSurface* src, 40716df86409ca586c3cb34f616f03501bd96181f9e4bsalomon const SkIRect& srcRect, 40726df86409ca586c3cb34f616f03501bd96181f9e4bsalomon const SkIPoint& dstPoint) { 4073e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon SkASSERT(can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this)); 40746df86409ca586c3cb34f616f03501bd96181f9e4bsalomon SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 40756df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.width(), srcRect.height()); 40766df86409ca586c3cb34f616f03501bd96181f9e4bsalomon if (dst == src) { 40776df86409ca586c3cb34f616f03501bd96181f9e4bsalomon if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { 40786df86409ca586c3cb34f616f03501bd96181f9e4bsalomon return false; 40796df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 40806df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 40816df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 40826df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLIRect dstVP; 40836df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLIRect srcVP; 408471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->bindSurfaceFBOForPixelOps(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget); 408571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->bindSurfaceFBOForPixelOps(src, GR_GL_READ_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget); 40866df86409ca586c3cb34f616f03501bd96181f9e4bsalomon // We modified the bound FBO 4087294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 40886df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLIRect srcGLRect; 40896df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLIRect dstGLRect; 40906df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcGLRect.setRelativeTo(srcVP, 40916df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.fLeft, 40926df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.fTop, 40936df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.width(), 40946df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcRect.height(), 40956df86409ca586c3cb34f616f03501bd96181f9e4bsalomon src->origin()); 40966df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstGLRect.setRelativeTo(dstVP, 40976df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstRect.fLeft, 40986df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstRect.fTop, 40996df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstRect.width(), 41006df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstRect.height(), 41016df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dst->origin()); 41026df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 41036df86409ca586c3cb34f616f03501bd96181f9e4bsalomon // BlitFrameBuffer respects the scissor, so disable it. 41046df86409ca586c3cb34f616f03501bd96181f9e4bsalomon this->disableScissor(); 410528341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton this->disableWindowRectangles(); 41066df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 41076df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLint srcY0; 41086df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GrGLint srcY1; 41096df86409ca586c3cb34f616f03501bd96181f9e4bsalomon // Does the blit need to y-mirror or not? 41106df86409ca586c3cb34f616f03501bd96181f9e4bsalomon if (src->origin() == dst->origin()) { 41116df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcY0 = srcGLRect.fBottom; 41126df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; 41136df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } else { 41146df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; 41156df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcY1 = srcGLRect.fBottom; 41166df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 41176df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GL_CALL(BlitFramebuffer(srcGLRect.fLeft, 41186df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcY0, 41196df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcGLRect.fLeft + srcGLRect.fWidth, 41206df86409ca586c3cb34f616f03501bd96181f9e4bsalomon srcY1, 41216df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstGLRect.fLeft, 41226df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstGLRect.fBottom, 41236df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstGLRect.fLeft + dstGLRect.fWidth, 41246df86409ca586c3cb34f616f03501bd96181f9e4bsalomon dstGLRect.fBottom + dstGLRect.fHeight, 41256df86409ca586c3cb34f616f03501bd96181f9e4bsalomon GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); 412671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->unbindTextureFBOForPixelOps(GR_GL_DRAW_FRAMEBUFFER, dst); 412771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon this->unbindTextureFBOForPixelOps(GR_GL_READ_FRAMEBUFFER, src); 4128083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon this->didWriteToSurface(dst, &dstRect); 41296df86409ca586c3cb34f616f03501bd96181f9e4bsalomon return true; 41306df86409ca586c3cb34f616f03501bd96181f9e4bsalomon} 41316df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 413233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman// Manual implementation of mipmap generation, to work around driver bugs w/sRGB. 413333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman// Uses draw calls to do a series of downsample operations to successive mips. 413433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman// If this returns false, then the calling code falls back to using glGenerateMipmap. 413533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosmanbool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) { 4136bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon SkASSERT(!GrPixelConfigIsSint(texture->config())); 413709563cec928da5052972b3dca7f022fca3a72d05brianosman // Our iterative downsample requires the ability to limit which level we're sampling: 413809563cec928da5052972b3dca7f022fca3a72d05brianosman if (!this->glCaps().doManualMipmapping()) { 413933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 414033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 414133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 414233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Mipmaps are only supported on 2D textures: 414333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (GR_GL_TEXTURE_2D != texture->target()) { 414433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 414533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 414633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 414733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // We need to be able to render to the texture for this to work: 414871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon if (!this->glCaps().canConfigBeFBOColorAttachment(texture->config())) { 414933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 415033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 415133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 415233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // If we're mipping an sRGB texture, we need to ensure FB sRGB is correct: 415333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (GrPixelConfigIsSRGB(texture->config())) { 415433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // If we have write-control, just set the state that we want: 415533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (this->glCaps().srgbWriteControl()) { 415633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->flushFramebufferSRGB(gammaCorrect); 415733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } else if (!gammaCorrect) { 415833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // If we don't have write-control we can't do non-gamma-correct mipmapping: 415933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 416033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 416133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 416233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 416333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman int width = texture->width(); 416433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman int height = texture->height(); 416533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1; 416633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 416733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Define all mips, if we haven't previously done so: 416833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (0 == texture->texturePriv().maxMipMapLevel()) { 416933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLenum internalFormat; 417033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLenum externalFormat; 417133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLenum externalType; 417233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!this->glCaps().getTexImageFormats(texture->config(), texture->config(), 417333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman &internalFormat, &externalFormat, &externalType)) { 417433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 417533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 417633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 417733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (GrGLint level = 1; level < levelCount; ++level) { 417833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Define the next mip: 417933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman width = SkTMax(1, width / 2); 418033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman height = SkTMax(1, height / 2); 418133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, level, internalFormat, 418233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman width, height, 0, 418333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman externalFormat, externalType, nullptr)); 418433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 418533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 418633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 418733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Create (if necessary), then bind temporary FBO: 418833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (0 == fTempDstFBOID) { 418933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(GenFramebuffers(1, &fTempDstFBOID)); 419033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 419133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID)); 4192294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundRenderTargetUniqueID.makeInvalid(); 419333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 419433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Bind the texture, to get things configured for filtering. 419533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // We'll be changing our base level further below: 419633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->setTextureUnit(0); 4197514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kBilerp_FilterMode); 419833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->bindTexture(0, params, gammaCorrect, texture); 419933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 420033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Vertex data: 420133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!fMipmapProgramArrayBuffer) { 420233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman static const GrGLfloat vdata[] = { 420333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 0, 0, 420433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 0, 1, 420533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 1, 0, 420633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 1, 1 420733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman }; 420833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fMipmapProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), 420933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman kVertex_GrBufferType, 421033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman kStatic_GrAccessPattern, vdata)); 421133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 421233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!fMipmapProgramArrayBuffer) { 421333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 421433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 421533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 421633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fHWVertexArrayState.setVertexArrayID(this, 0); 421733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 421833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); 4219144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary attribs->set(this, 0, fMipmapProgramArrayBuffer.get(), kVec2f_GrVertexAttribType, 422033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 2 * sizeof(GrGLfloat), 0); 422133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman attribs->disableUnusedArrays(this, 0x1); 422233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 422333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Set "simple" state once: 422433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrXferProcessor::BlendInfo blendInfo; 422533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman blendInfo.reset(); 422633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->flushBlend(blendInfo, GrSwizzle::RGBA()); 422733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->flushColorWrite(true); 42285fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips this->flushDrawFace(GrDrawFace::kBoth); 422933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->flushHWAAState(nullptr, false, false); 423033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->disableScissor(); 423128341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton this->disableWindowRectangles(); 4232c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton this->disableStencil(); 423333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 423433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Do all the blits: 423533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman width = texture->width(); 423633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman height = texture->height(); 423733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GrGLIRect viewport; 423833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman viewport.fLeft = 0; 423933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman viewport.fBottom = 0; 424033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman for (GrGLint level = 1; level < levelCount; ++level) { 424133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Get and bind the program for this particular downsample (filter shape can vary): 424233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman int progIdx = TextureSizeToMipmapProgramIdx(width, height); 424333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!fMipmapPrograms[progIdx].fProgram) { 424433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman if (!this->createMipmapProgram(progIdx)) { 424533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman SkDebugf("Failed to create mipmap program.\n"); 424633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return false; 424733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 424833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 424933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(UseProgram(fMipmapPrograms[progIdx].fProgram)); 425033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman fHWProgramID = fMipmapPrograms[progIdx].fProgram; 425133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 425233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Texcoord uniform is expected to contain (1/w, (w-1)/w, 1/h, (h-1)/h) 425333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman const float invWidth = 1.0f / width; 425433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman const float invHeight = 1.0f / height; 425533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(Uniform4f(fMipmapPrograms[progIdx].fTexCoordXformUniform, 425633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman invWidth, (width - 1) * invWidth, invHeight, (height - 1) * invHeight)); 425733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(Uniform1i(fMipmapPrograms[progIdx].fTextureUniform, 0)); 425833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 425933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Only sample from previous mip 426033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level - 1)); 426133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 426233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, 426333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GR_GL_TEXTURE_2D, texture->textureID(), level)); 426433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 426533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman width = SkTMax(1, width / 2); 426633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman height = SkTMax(1, height / 2); 426733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman viewport.fWidth = width; 426833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman viewport.fHeight = height; 426933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman this->flushViewport(viewport); 427033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 427133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); 427233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman } 427333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 427433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman // Unbind: 427533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, 427633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman GR_GL_TEXTURE_2D, 0, 0)); 427733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 427833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman return true; 427933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman} 428033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman 4281c25c5d73e9f4d840dc758c399496d5690709ad58csmartdaltonvoid GrGLGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings& stencil, 4282c25c5d73e9f4d840dc758c399496d5690709ad58csmartdalton int* effectiveSampleCnt, SamplePattern* samplePattern) { 4283f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton SkASSERT(!rt->isMixedSampled() || rt->renderTargetPriv().getStencilAttachment() || 428428f45b949acc746849100fbe112ee5280f0594c9cdalton stencil.isDisabled()); 428528f45b949acc746849100fbe112ee5280f0594c9cdalton 428628f45b949acc746849100fbe112ee5280f0594c9cdalton this->flushStencil(stencil); 428728f45b949acc746849100fbe112ee5280f0594c9cdalton this->flushHWAAState(rt, true, !stencil.isDisabled()); 428828f45b949acc746849100fbe112ee5280f0594c9cdalton this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyIRect()); 428928f45b949acc746849100fbe112ee5280f0594c9cdalton 429028f45b949acc746849100fbe112ee5280f0594c9cdalton if (0 != this->caps()->maxRasterSamples()) { 429128f45b949acc746849100fbe112ee5280f0594c9cdalton GR_GL_GetIntegerv(this->glInterface(), GR_GL_EFFECTIVE_RASTER_SAMPLES, effectiveSampleCnt); 429228f45b949acc746849100fbe112ee5280f0594c9cdalton } else { 429328f45b949acc746849100fbe112ee5280f0594c9cdalton GR_GL_GetIntegerv(this->glInterface(), GR_GL_SAMPLES, effectiveSampleCnt); 429428f45b949acc746849100fbe112ee5280f0594c9cdalton } 429528f45b949acc746849100fbe112ee5280f0594c9cdalton 429628f45b949acc746849100fbe112ee5280f0594c9cdalton SkASSERT(*effectiveSampleCnt >= rt->desc().fSampleCnt); 429728f45b949acc746849100fbe112ee5280f0594c9cdalton 429828f45b949acc746849100fbe112ee5280f0594c9cdalton if (this->caps()->sampleLocationsSupport()) { 42990d28e574ac73fef8bf75cab083ffe23f2d8860a1csmartdalton samplePattern->reset(*effectiveSampleCnt); 430028f45b949acc746849100fbe112ee5280f0594c9cdalton for (int i = 0; i < *effectiveSampleCnt; ++i) { 430128f45b949acc746849100fbe112ee5280f0594c9cdalton GrGLfloat pos[2]; 430228f45b949acc746849100fbe112ee5280f0594c9cdalton GL_CALL(GetMultisamplefv(GR_GL_SAMPLE_POSITION, i, pos)); 430328f45b949acc746849100fbe112ee5280f0594c9cdalton if (kTopLeft_GrSurfaceOrigin == rt->origin()) { 43040d28e574ac73fef8bf75cab083ffe23f2d8860a1csmartdalton (*samplePattern)[i].set(pos[0], pos[1]); 430528f45b949acc746849100fbe112ee5280f0594c9cdalton } else { 43060d28e574ac73fef8bf75cab083ffe23f2d8860a1csmartdalton (*samplePattern)[i].set(pos[0], 1 - pos[1]); 430728f45b949acc746849100fbe112ee5280f0594c9cdalton } 430828f45b949acc746849100fbe112ee5280f0594c9cdalton } 430928f45b949acc746849100fbe112ee5280f0594c9cdalton } 431028f45b949acc746849100fbe112ee5280f0594c9cdalton} 431128f45b949acc746849100fbe112ee5280f0594c9cdalton 4312231c5fd590c898957d65cbfbc51040c7fe236af6cdaltonvoid GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { 4313cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon SkASSERT(type); 43149954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton switch (type) { 4315231c5fd590c898957d65cbfbc51040c7fe236af6cdalton case kTexture_GrXferBarrierType: { 4316231c5fd590c898957d65cbfbc51040c7fe236af6cdalton GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); 4317231c5fd590c898957d65cbfbc51040c7fe236af6cdalton if (glrt->textureFBOID() != glrt->renderFBOID()) { 4318231c5fd590c898957d65cbfbc51040c7fe236af6cdalton // The render target uses separate storage so no need for glTextureBarrier. 4319231c5fd590c898957d65cbfbc51040c7fe236af6cdalton // FIXME: The render target will resolve automatically when its texture is bound, 4320231c5fd590c898957d65cbfbc51040c7fe236af6cdalton // but we could resolve only the bounds that will be read if we do it here instead. 4321231c5fd590c898957d65cbfbc51040c7fe236af6cdalton return; 4322231c5fd590c898957d65cbfbc51040c7fe236af6cdalton } 43239954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton SkASSERT(this->caps()->textureBarrierSupport()); 43249954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton GL_CALL(TextureBarrier()); 43259954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton return; 4326231c5fd590c898957d65cbfbc51040c7fe236af6cdalton } 43278917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton case kBlend_GrXferBarrierType: 43284b91f768b348aa1cebeb54f3ff9331938734c242bsalomon SkASSERT(GrCaps::kAdvanced_BlendEquationSupport == 43298917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton this->caps()->blendEquationSupport()); 43308917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton GL_CALL(BlendBarrier()); 43318917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton return; 4332cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon default: break; // placate compiler warnings that kNone not handled 43339954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton } 43349954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton} 43359954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton 4336889579287770ba35156a73aa02d9ef5d2313c490jvanverthGrBackendObject GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, 43370a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel GrPixelConfig config, bool /*isRT*/) { 4338926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon if (!this->caps()->isConfigTexturable(config)) { 4339926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon return false; 4340926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon } 434118b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner std::unique_ptr<GrGLTextureInfo> info = skstd::make_unique<GrGLTextureInfo>(); 4342091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon info->fTarget = GR_GL_TEXTURE_2D; 4343546eb5c57aebee47172f9d2a3eae6b49945dba08kkinnunen info->fID = 0; 4344091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(GenTextures(1, &info->fID)); 4345672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth GL_CALL(ActiveTexture(GR_GL_TEXTURE0)); 4346672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1)); 4347091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(BindTexture(info->fTarget, info->fID)); 4348294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fHWBoundTextureUniqueIDs[0].makeInvalid(); 4349091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST)); 4350091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST)); 4351091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE)); 4352091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE)); 4353672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 435476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum internalFormat; 435576148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalFormat; 435676148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon GrGLenum externalType; 435776148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon 435876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat, 435976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon &externalType)) { 436076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon return reinterpret_cast<GrBackendObject>(nullptr); 436176148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon } 4362672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 4363091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GL_CALL(TexImage2D(info->fTarget, 0, internalFormat, w, h, 0, externalFormat, 4364672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth externalType, pixels)); 4365672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 436618b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner return reinterpret_cast<GrBackendObject>(info.release()); 4367672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth} 4368672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 4369889579287770ba35156a73aa02d9ef5d2313c490jvanverthbool GrGLGpu::isTestingOnlyBackendTexture(GrBackendObject id) const { 4370091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GrGLuint texID = reinterpret_cast<const GrGLTextureInfo*>(id)->fID; 4371672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 4372672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth GrGLboolean result; 4373672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth GL_CALL_RET(result, IsTexture(texID)); 4374672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 4375672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth return (GR_GL_TRUE == result); 4376672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth} 4377672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 4378e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomonvoid GrGLGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandonTexture) { 437918b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner std::unique_ptr<const GrGLTextureInfo> info(reinterpret_cast<const GrGLTextureInfo*>(id)); 4380091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon GrGLuint texID = info->fID; 4381091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon 438267d7620285cdfa60158add6615db03bd48e6d8b0bsalomon if (!abandonTexture) { 438367d7620285cdfa60158add6615db03bd48e6d8b0bsalomon GL_CALL(DeleteTextures(1, &texID)); 438467d7620285cdfa60158add6615db03bd48e6d8b0bsalomon } 4385672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth} 4386672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 43878fd844f38ed46eaac78bb187623ffcc40b592707joshualittvoid GrGLGpu::resetShaderCacheForTesting() const { 43888fd844f38ed46eaac78bb187623ffcc40b592707joshualitt fProgramCache->abandon(); 43898fd844f38ed46eaac78bb187623ffcc40b592707joshualitt} 43908fd844f38ed46eaac78bb187623ffcc40b592707joshualitt 43916918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 43926df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 4393e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonGrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu, 4394485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton const GrBuffer* ibuf) { 43954f65a2750007725349774e53067df3307376257crobertphillips@google.com GrGLAttribArrayState* attribState; 43964f65a2750007725349774e53067df3307376257crobertphillips@google.com 4397e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (gpu->glCaps().isCoreProfile()) { 4398e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (!fCoreProfileVertexArray) { 43996918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GrGLuint arrayID; 44006918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); 44016918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com int attrCount = gpu->glCaps().maxVertexAttributes(); 4402e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton fCoreProfileVertexArray = new GrGLVertexArray(arrayID, attrCount); 44037acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com } 4404e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (ibuf) { 4405e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton attribState = fCoreProfileVertexArray->bindWithIndexBuffer(gpu, ibuf); 44066df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } else { 4407e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton attribState = fCoreProfileVertexArray->bind(gpu); 44086df86409ca586c3cb34f616f03501bd96181f9e4bsalomon } 44096918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } else { 4410e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton if (ibuf) { 4411e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton // bindBuffer implicitly binds VAO 0 when binding an index buffer. 4412e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton gpu->bindBuffer(kIndex_GrBufferType, ibuf); 44136918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } else { 44146918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com this->setVertexArrayID(gpu, 0); 4415880b8fcf255e67a15687e8b7cc47397372db683cbsalomon@google.com } 44166918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com int attrCount = gpu->glCaps().maxVertexAttributes(); 44176918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com if (fDefaultVertexArrayAttribState.count() != attrCount) { 44186918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com fDefaultVertexArrayAttribState.resize(attrCount); 44197acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com } 44206918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com attribState = &fDefaultVertexArrayAttribState; 44217acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com } 44226918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com return attribState; 44237acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com} 4424e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 44253798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillipsbool GrGLGpu::onIsACopyNeededForTextureParams(GrTextureProxy* proxy, 442681444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips const GrSamplerParams& textureParams, 442781444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips GrTextureProducer::CopyParams* copyParams, 442881444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips SkScalar scaleAdjust[2]) const { 44293798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips const GrTexture* texture = proxy->priv().peekTexture(); 44303798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips if (!texture) { 44313798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips // The only way to get and EXTERNAL or RECTANGLE texture in Ganesh is to wrap them. 44323798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips // In that case the proxy should already be instantiated. 44333798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips return false; 44343798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips } 44353798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips 4436e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (textureParams.isTiled() || 4437514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon GrSamplerParams::kMipMap_FilterMode == textureParams.filterMode()) { 44383798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips const GrGLTexture* glTexture = static_cast<const GrGLTexture*>(texture); 4439e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || 4440e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { 4441514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon copyParams->fFilter = GrSamplerParams::kNone_FilterMode; 4442e179a9167f71dfc41668b05d40082aae76367fa6bsalomon copyParams->fWidth = texture->width(); 4443e179a9167f71dfc41668b05d40082aae76367fa6bsalomon copyParams->fHeight = texture->height(); 4444e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return true; 4445e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 4446e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 4447e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return false; 4448e179a9167f71dfc41668b05d40082aae76367fa6bsalomon} 444984741b308496409f4ff662658167221fc6801bbejvanverth 44506be35238855dbbc7575e78d6723936293a4b38e6Greg DanielGrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() { 44516be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GrGLsync sync; 44526be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); 44536be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GR_STATIC_ASSERT(sizeof(GrFence) >= sizeof(GrGLsync)); 44546be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel return (GrFence)sync; 445584741b308496409f4ff662658167221fc6801bbejvanverth} 445684741b308496409f4ff662658167221fc6801bbejvanverth 44576be35238855dbbc7575e78d6723936293a4b38e6Greg Danielbool GrGLGpu::waitFence(GrFence fence, uint64_t timeout) { 445884741b308496409f4ff662658167221fc6801bbejvanverth GrGLenum result; 445984741b308496409f4ff662658167221fc6801bbejvanverth GL_CALL_RET(result, ClientWaitSync((GrGLsync)fence, GR_GL_SYNC_FLUSH_COMMANDS_BIT, timeout)); 446084741b308496409f4ff662658167221fc6801bbejvanverth return (GR_GL_CONDITION_SATISFIED == result); 446184741b308496409f4ff662658167221fc6801bbejvanverth} 446284741b308496409f4ff662658167221fc6801bbejvanverth 446384741b308496409f4ff662658167221fc6801bbejvanverthvoid GrGLGpu::deleteFence(GrFence fence) const { 44646be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel this->deleteSync((GrGLsync)fence); 44656be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel} 44666be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 44676be35238855dbbc7575e78d6723936293a4b38e6Greg Danielsk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrGLGpu::makeSemaphore() { 44686be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel return GrGLSemaphore::Make(this); 44696be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel} 44706be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 44716be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrGLGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore) { 44726be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get()); 44736be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 44746be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GrGLsync sync; 44756be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); 44766be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel glSem->setSync(sync); 44776be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel} 44786be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 44796be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrGLGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) { 44806be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get()); 44816be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 44826be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GL_CALL(WaitSync(glSem->sync(), 0, GR_GL_TIMEOUT_IGNORED)); 44836be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel} 44846be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 44856be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrGLGpu::deleteSync(GrGLsync sync) const { 44866be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GL_CALL(DeleteSync(sync)); 448784741b308496409f4ff662658167221fc6801bbejvanverth} 44882c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman 44892c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osmanvoid GrGLGpu::flush() { 44902c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman GL_CALL(Flush()); 44912c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman} 4492