aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-02-14 14:09:57 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-02-14 14:09:57 +0000
commitf7fa806d84abf1cba47bfa8679e875a75d76599e (patch)
tree33e3926acc36d740deac496bbe674cf02dfd6c53 /src
parentb1e218e782261304440199642f1b98e7ba96b525 (diff)
Make GLCaps be standalone and be a member of GrGLContextInfo
Review URL: http://codereview.appspot.com/5654084/ git-svn-id: http://skia.googlecode.com/svn/trunk@3183 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/gpu/gl/GrGLCaps.cpp295
-rw-r--r--src/gpu/gl/GrGLCaps.h227
-rw-r--r--src/gpu/gl/GrGLContextInfo.cpp3
-rw-r--r--src/gpu/gl/GrGLContextInfo.h4
-rw-r--r--src/gpu/gl/GrGLStencilBuffer.h1
-rw-r--r--src/gpu/gl/GrGpuGL.cpp338
-rw-r--r--src/gpu/gl/GrGpuGL.h115
-rw-r--r--src/gpu/gl/GrGpuGLShaders.cpp2
8 files changed, 577 insertions, 408 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
new file mode 100644
index 0000000000..d690ff3fe1
--- /dev/null
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -0,0 +1,295 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "GrGLCaps.h"
+#include "GrGLContextInfo.h"
+
+GrGLCaps::GrGLCaps() {
+ this->reset();
+}
+
+void GrGLCaps::reset() {
+ fVerifiedColorConfigs.reset();
+ fStencilFormats.reset();
+ fStencilVerifiedColorConfigs.reset();
+ fMSFBOType = kNone_MSFBOType;
+ fMaxFragmentUniformVectors = 0;
+ fRGBA8RenderbufferSupport = false;
+ fBGRAFormatSupport = false;
+ fBGRAIsInternalFormat = false;
+ fTextureSwizzleSupport = false;
+ fUnpackRowLengthSupport = false;
+ fUnpackFlipYSupport = false;
+ fPackRowLengthSupport = false;
+ fPackFlipYSupport = false;
+ fTextureUsageSupport = false;
+ fTexStorageSupport = false;
+}
+
+GrGLCaps::GrGLCaps(const GrGLCaps& caps) {
+ *this = caps;
+}
+
+GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
+ fVerifiedColorConfigs = caps.fVerifiedColorConfigs;
+ fStencilFormats = caps.fStencilFormats;
+ fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs;
+ fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors;
+ fMSFBOType = caps.fMSFBOType;
+ fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
+ fBGRAFormatSupport = caps.fBGRAFormatSupport;
+ fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat;
+ fTextureSwizzleSupport = caps.fTextureSwizzleSupport;
+ fUnpackRowLengthSupport = caps.fUnpackRowLengthSupport;
+ fUnpackFlipYSupport = caps.fUnpackFlipYSupport;
+ fPackRowLengthSupport = caps.fPackRowLengthSupport;
+ fPackFlipYSupport = caps.fPackFlipYSupport;
+ fTextureUsageSupport = caps.fTextureUsageSupport;
+ fTexStorageSupport = caps.fTexStorageSupport;
+
+ return *this;
+}
+
+void GrGLCaps::init(const GrGLContextInfo& ctxInfo) {
+
+ this->reset();
+ if (!ctxInfo.isInitialized()) {
+ return;
+ }
+
+ const GrGLInterface* gli = ctxInfo.interface();
+ GrGLBinding binding = ctxInfo.binding();
+ GrGLVersion version = ctxInfo.version();
+
+ if (kES2_GrGLBinding == binding) {
+ GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
+ &fMaxFragmentUniformVectors);
+ } else {
+ GrAssert(kDesktop_GrGLBinding == binding);
+ GrGLint max;
+ GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
+ fMaxFragmentUniformVectors = max / 4;
+ }
+
+ if (kDesktop_GrGLBinding == binding) {
+ fRGBA8RenderbufferSupport = true;
+ } else {
+ fRGBA8RenderbufferSupport = ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
+ ctxInfo.hasExtension("GL_ARM_rgba8");
+ }
+
+ if (kDesktop_GrGLBinding == binding) {
+ fBGRAFormatSupport = version >= GR_GL_VER(1,2) ||
+ ctxInfo.hasExtension("GL_EXT_bgra");
+ } else {
+ bool hasBGRAExt = false;
+ if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
+ fBGRAFormatSupport = true;
+ } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
+ fBGRAFormatSupport = true;
+ fBGRAIsInternalFormat = true;
+ }
+ GrAssert(fBGRAFormatSupport ||
+ kSkia8888_PM_GrPixelConfig != kBGRA_8888_PM_GrPixelConfig);
+ }
+
+ if (kDesktop_GrGLBinding == binding) {
+ fTextureSwizzleSupport = version >= GR_GL_VER(3,3) ||
+ ctxInfo.hasExtension("GL_ARB_texture_swizzle");
+ } else {
+ fTextureSwizzleSupport = false;
+ }
+
+ if (kDesktop_GrGLBinding == binding) {
+ fUnpackRowLengthSupport = true;
+ fUnpackFlipYSupport = false;
+ fPackRowLengthSupport = true;
+ fPackFlipYSupport = false;
+ } else {
+ fUnpackRowLengthSupport =ctxInfo.hasExtension("GL_EXT_unpack_subimage");
+ fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
+ // no extension for pack row length
+ fPackRowLengthSupport = false;
+ fPackFlipYSupport =
+ ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
+ }
+
+ fTextureUsageSupport = (kES2_GrGLBinding == binding) &&
+ ctxInfo.hasExtension("GL_ANGLE_texture_usage");
+
+ // Tex storage is in desktop 4.2 and can be an extension to desktop or ES.
+ fTexStorageSupport = (kDesktop_GrGLBinding == binding &&
+ version >= GR_GL_VER(4,2)) ||
+ ctxInfo.hasExtension("GL_ARB_texture_storage") ||
+ ctxInfo.hasExtension("GL_EXT_texture_storage");
+
+ this->initFSAASupport(ctxInfo);
+ this->initStencilFormats(ctxInfo);
+}
+
+void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo) {
+
+ fMSFBOType = kNone_MSFBOType;
+ if (kDesktop_GrGLBinding != ctxInfo.binding()) {
+ if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
+ // chrome's extension is equivalent to the EXT msaa
+ // and fbo_blit extensions.
+ fMSFBOType = kDesktopEXT_MSFBOType;
+ } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
+ fMSFBOType = kAppleES_MSFBOType;
+ }
+ } else {
+ if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
+ ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
+ fMSFBOType = GrGLCaps::kDesktopARB_MSFBOType;
+ } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
+ ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
+ fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType;
+ }
+ }
+}
+
+namespace {
+const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
+}
+
+void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
+
+ // Build up list of legal stencil formats (though perhaps not supported on
+ // the particular gpu/driver) from most preferred to least.
+
+ // these consts are in order of most preferred to least preferred
+ // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
+
+ static const StencilFormat
+ // internal Format stencil bits total bits packed?
+ gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
+ gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
+ gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
+ gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
+ gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
+ gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
+
+ if (kDesktop_GrGLBinding == ctxInfo.binding()) {
+ bool supportsPackedDS =
+ ctxInfo.version() >= GR_GL_VER(3,0) ||
+ ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
+ ctxInfo.hasExtension("GL_ARB_framebuffer_object");
+
+ // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
+ // require FBO support we can expect these are legal formats and don't
+ // check. These also all support the unsized GL_STENCIL_INDEX.
+ fStencilFormats.push_back() = gS8;
+ fStencilFormats.push_back() = gS16;
+ if (supportsPackedDS) {
+ fStencilFormats.push_back() = gD24S8;
+ }
+ fStencilFormats.push_back() = gS4;
+ if (supportsPackedDS) {
+ fStencilFormats.push_back() = gDS;
+ }
+ } else {
+ // ES2 has STENCIL_INDEX8 without extensions but requires extensions
+ // for other formats.
+ // ES doesn't support using the unsized format.
+
+ fStencilFormats.push_back() = gS8;
+ //fStencilFormats.push_back() = gS16;
+ if (ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
+ fStencilFormats.push_back() = gD24S8;
+ }
+ if (ctxInfo.hasExtension("GL_OES_stencil4")) {
+ fStencilFormats.push_back() = gS4;
+ }
+ }
+ GrAssert(0 == fStencilVerifiedColorConfigs.count());
+ fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count());
+}
+
+void GrGLCaps::markColorConfigAndStencilFormatAsVerified(
+ GrPixelConfig config,
+ const GrGLStencilBuffer::Format& format) {
+#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
+ return;
+#endif
+ GrAssert((unsigned)config < kGrPixelConfigCount);
+ GrAssert(fStencilFormats.count() == fStencilVerifiedColorConfigs.count());
+ int count = fStencilFormats.count();
+ // we expect a really small number of possible formats so linear search
+ // should be OK
+ GrAssert(count < 16);
+ for (int i = 0; i < count; ++i) {
+ if (format.fInternalFormat ==
+ fStencilFormats[i].fInternalFormat) {
+ fStencilVerifiedColorConfigs[i].markVerified(config);
+ return;
+ }
+ }
+ GrCrash("Why are we seeing a stencil format that "
+ "GrGLCaps doesn't know about.");
+}
+
+bool GrGLCaps::isColorConfigAndStencilFormatVerified(
+ GrPixelConfig config,
+ const GrGLStencilBuffer::Format& format) const {
+#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
+ return false;
+#endif
+ GrAssert((unsigned)config < kGrPixelConfigCount);
+ int count = fStencilFormats.count();
+ // we expect a really small number of possible formats so linear search
+ // should be OK
+ GrAssert(count < 16);
+ for (int i = 0; i < count; ++i) {
+ if (format.fInternalFormat ==
+ fStencilFormats[i].fInternalFormat) {
+ return fStencilVerifiedColorConfigs[i].isVerified(config);
+ }
+ }
+ GrCrash("Why are we seeing a stencil format that "
+ "GLCaps doesn't know about.");
+ return false;
+}
+
+void GrGLCaps::print() const {
+ for (int i = 0; i < fStencilFormats.count(); ++i) {
+ GrPrintf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
+ i,
+ fStencilFormats[i].fStencilBits,
+ fStencilFormats[i].fTotalBits);
+ }
+
+ GR_STATIC_ASSERT(0 == kNone_MSFBOType);
+ GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType);
+ GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType);
+ GR_STATIC_ASSERT(3 == kAppleES_MSFBOType);
+ static const char* gMSFBOExtStr[] = {
+ "None",
+ "ARB",
+ "EXT",
+ "Apple",
+ };
+ GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
+ GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
+ GrPrintf("Support RGBA8 Render Buffer: %s\n",
+ (fRGBA8RenderbufferSupport ? "YES": "NO"));
+ GrPrintf("BGRA is an internal format: %s\n",
+ (fBGRAIsInternalFormat ? "YES": "NO"));
+ GrPrintf("Support texture swizzle: %s\n",
+ (fTextureSwizzleSupport ? "YES": "NO"));
+ GrPrintf("Unpack Row length support: %s\n",
+ (fUnpackRowLengthSupport ? "YES": "NO"));
+ GrPrintf("Unpack Flip Y support: %s\n",
+ (fUnpackFlipYSupport ? "YES": "NO"));
+ GrPrintf("Pack Row length support: %s\n",
+ (fPackRowLengthSupport ? "YES": "NO"));
+ GrPrintf("Pack Flip Y support: %s\n",
+ (fPackFlipYSupport ? "YES": "NO"));
+}
+
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
new file mode 100644
index 0000000000..a5318ebde8
--- /dev/null
+++ b/src/gpu/gl/GrGLCaps.h
@@ -0,0 +1,227 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrGLCaps_DEFINED
+#define GrGLCaps_DEFINED
+
+#include "GrGLStencilBuffer.h"
+
+class GrGLContextInfo;
+
+/**
+ * Stores some capabilities of a GL context. Most are determined by the GL
+ * version and the extensions string. It also tracks formats that have passed
+ * the FBO completeness test.
+ */
+class GrGLCaps {
+public:
+ typedef GrGLStencilBuffer::Format StencilFormat;
+
+ /**
+ * The type of MSAA for FBOs supported. Different extensions have different
+ * semantics of how / when a resolve is performed.
+ */
+ enum MSFBOType {
+ /**
+ * no support for MSAA FBOs
+ */
+ kNone_MSFBOType = 0,
+ /**
+ * GL3.0-style MSAA FBO (GL_ARB_framebuffer_object)
+ */
+ kDesktopARB_MSFBOType,
+ /**
+ * earlier GL_EXT_framebuffer* extensions
+ */
+ kDesktopEXT_MSFBOType,
+ /**
+ * GL_APPLE_framebuffer_multisample ES extension
+ */
+ kAppleES_MSFBOType,
+ };
+
+ /**
+ * Creates a GrGLCaps that advertises no support for any extensions,
+ * formats, etc. Call init to initialize from a GrGLContextInfo.
+ */
+ GrGLCaps();
+
+ GrGLCaps(const GrGLCaps& caps);
+
+ GrGLCaps& operator = (const GrGLCaps& caps);
+
+ /**
+ * Resets the caps such that nothing is supported.
+ */
+ void reset();
+
+ /**
+ * Initializes the GrGLCaps to the set of features supported in the current
+ * OpenGL context accessible via ctxInfo.
+ */
+ void init(const GrGLContextInfo& ctxInfo);
+
+ /**
+ * Call to note that a color config has been verified as a valid color
+ * attachment. This may save future calls to glCheckFramebufferStatus
+ * using isConfigVerifiedColorAttachment().
+ */
+ void markConfigAsValidColorAttachment(GrPixelConfig config) {
+ fVerifiedColorConfigs.markVerified(config);
+ }
+
+ /**
+ * Call to check whether a config has been verified as a valid color
+ * attachment.
+ */
+ bool isConfigVerifiedColorAttachment(GrPixelConfig config) const {
+ return fVerifiedColorConfigs.isVerified(config);
+ }
+
+ /**
+ * Call to note that a color config / stencil format pair passed
+ * FBO status check. We may skip calling glCheckFramebufferStatus for
+ * this combination in the future using
+ * isColorConfigAndStencilFormatVerified().
+ */
+ void markColorConfigAndStencilFormatAsVerified(
+ GrPixelConfig config,
+ const GrGLStencilBuffer::Format& format);
+
+ /**
+ * Call to check whether color config / stencil format pair has already
+ * passed FBO status check.
+ */
+ bool isColorConfigAndStencilFormatVerified(
+ GrPixelConfig config,
+ const GrGLStencilBuffer::Format& format) const;
+
+ /**
+ * Reports the type of MSAA FBO support.
+ */
+ MSFBOType msFBOType() const { return fMSFBOType; }
+
+ /**
+ * Prints the caps info using GrPrintf.
+ */
+ void print() const;
+
+ /**
+ * Gets an array of legal stencil formats. These formats are not guaranteed
+ * to be supported by the driver but are legal GLenum names given the GL
+ * version and extensions supported.
+ */
+ const SkTArray<StencilFormat, true>& stencilFormats() const {
+ return fStencilFormats;
+ }
+
+ /// The maximum number of fragment uniform vectors (GLES has min. 16).
+ int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
+
+ /// ES requires an extension to support RGBA8 in RenderBufferStorage
+ bool rgba8RenderbufferSupport() const { return fRGBA8RenderbufferSupport; }
+
+ /// Is GL_BGRA supported
+ bool bgraFormatSupport() const { return fBGRAFormatSupport; }
+
+ /**
+ * Depending on the ES extensions present the BGRA external format may
+ * correspond either a BGRA or RGBA internalFormat. On desktop GL it is
+ * RGBA.
+ */
+ bool bgraIsInternalFormat() const { return fBGRAIsInternalFormat; }
+
+ /// GL_ARB_texture_swizzle support
+ bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
+
+ /// Is there support for GL_UNPACK_ROW_LENGTH
+ bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
+
+ /// Is there support for GL_UNPACK_FLIP_Y
+ bool unpackFlipYSupport() const { return fUnpackFlipYSupport; }
+
+ /// Is there support for GL_PACK_ROW_LENGTH
+ bool packRowLengthSupport() const { return fPackRowLengthSupport; }
+
+ /// Is there support for GL_PACK_REVERSE_ROW_ORDER
+ bool packFlipYSupport() const { return fPackFlipYSupport; }
+
+ /// Is there support for texture parameter GL_TEXTURE_USAGE
+ bool textureUsageSupport() const { return fTextureUsageSupport; }
+
+ /// Is there support for glTexStorage
+ bool texStorageSupport() const { return fTexStorageSupport; }
+
+private:
+ /**
+ * Maintains a bit per GrPixelConfig. It is used to avoid redundantly
+ * performing glCheckFrameBufferStatus for the same config.
+ */
+ struct VerifiedColorConfigs {
+ VerifiedColorConfigs() {
+ this->reset();
+ }
+
+ void reset() {
+ for (int i = 0; i < kNumUints; ++i) {
+ fVerifiedColorConfigs[i] = 0;
+ }
+ }
+
+ static const int kNumUints = (kGrPixelConfigCount + 31) / 32;
+ uint32_t fVerifiedColorConfigs[kNumUints];
+
+ void markVerified(GrPixelConfig config) {
+#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
+ return;
+#endif
+ int u32Idx = config / 32;
+ int bitIdx = config % 32;
+ fVerifiedColorConfigs[u32Idx] |= 1 << bitIdx;
+ }
+
+ bool isVerified(GrPixelConfig config) const {
+#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
+ return false;
+#endif
+ int u32Idx = config / 32;
+ int bitIdx = config % 32;
+ return SkToBool(fVerifiedColorConfigs[u32Idx] & (1 << bitIdx));
+ }
+ };
+
+ void initFSAASupport(const GrGLContextInfo& ctxInfo);
+ void initStencilFormats(const GrGLContextInfo& ctxInfo);
+
+ // tracks configs that have been verified to pass the FBO completeness when
+ // used as a color attachment
+ VerifiedColorConfigs fVerifiedColorConfigs;
+
+ SkTArray<StencilFormat, true> fStencilFormats;
+ // tracks configs that have been verified to pass the FBO completeness when
+ // used as a color attachment when a particular stencil format is used
+ // as a stencil attachment.
+ SkTArray<VerifiedColorConfigs, true> fStencilVerifiedColorConfigs;
+
+ int fMaxFragmentUniformVectors;
+ MSFBOType fMSFBOType;
+
+ bool fRGBA8RenderbufferSupport : 1;
+ bool fBGRAFormatSupport : 1;
+ bool fBGRAIsInternalFormat : 1;
+ bool fTextureSwizzleSupport : 1;
+ bool fUnpackRowLengthSupport : 1;
+ bool fUnpackFlipYSupport : 1;
+ bool fPackRowLengthSupport : 1;
+ bool fPackFlipYSupport : 1;
+ bool fTextureUsageSupport : 1;
+ bool fTexStorageSupport : 1;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLContextInfo.cpp b/src/gpu/gl/GrGLContextInfo.cpp
index 6fa7d8a93b..33e19ab060 100644
--- a/src/gpu/gl/GrGLContextInfo.cpp
+++ b/src/gpu/gl/GrGLContextInfo.cpp
@@ -32,6 +32,7 @@ GrGLContextInfo& GrGLContextInfo::operator = (const GrGLContextInfo& ctx) {
fGLVersion = ctx.fGLVersion;
fGLSLGeneration = ctx.fGLSLGeneration;
fExtensionString = ctx.fExtensionString;
+ fGLCaps = ctx.fGLCaps;
return *this;
}
@@ -41,6 +42,7 @@ void GrGLContextInfo::reset() {
fGLVersion = GR_GL_VER(0, 0);
fGLSLGeneration = static_cast<GrGLSLGeneration>(0);
fExtensionString = "";
+ fGLCaps.reset();
}
bool GrGLContextInfo::initialize(const GrGLInterface* interface) {
@@ -70,6 +72,7 @@ bool GrGLContextInfo::initialize(const GrGLInterface* interface) {
GR_GL_CALL_RET(interface, ext, GetString(GR_GL_EXTENSIONS));
fExtensionString = reinterpret_cast<const char*>(ext);
+ fGLCaps.init(*this);
return true;
}
}
diff --git a/src/gpu/gl/GrGLContextInfo.h b/src/gpu/gl/GrGLContextInfo.h
index bf77656624..b753608558 100644
--- a/src/gpu/gl/GrGLContextInfo.h
+++ b/src/gpu/gl/GrGLContextInfo.h
@@ -10,6 +10,7 @@
#ifndef GrGLContextInfo_DEFINED
#define GrGLContextInfo_DEFINED
+#include "GrGLCaps.h"
#include "GrGLInterface.h"
#include "GrGLSL.h"
@@ -57,6 +58,8 @@ public:
GrGLBinding binding() const { return fBindingInUse; }
GrGLVersion version() const { return fGLVersion; }
GrGLSLGeneration glslGeneration() const { return fGLSLGeneration; }
+ const GrGLCaps& caps() const { return fGLCaps; }
+ GrGLCaps& caps() { return fGLCaps; }
/**
* Checks for extension support using a cached copy of the GL_EXTENSIONS
@@ -77,6 +80,7 @@ private:
GrGLVersion fGLVersion;
GrGLSLGeneration fGLSLGeneration;
SkString fExtensionString;
+ GrGLCaps fGLCaps;
};
#endif
diff --git a/src/gpu/gl/GrGLStencilBuffer.h b/src/gpu/gl/GrGLStencilBuffer.h
index 02501e7cd2..0995c7dff0 100644
--- a/src/gpu/gl/GrGLStencilBuffer.h
+++ b/src/gpu/gl/GrGLStencilBuffer.h
@@ -16,6 +16,7 @@
class GrGLStencilBuffer : public GrStencilBuffer {
public:
static const GrGLenum kUnknownInternalFormat = ~0;
+ static const GrGLuint kUnknownBitCount = ~0;
struct Format {
GrGLenum fInternalFormat;
GrGLuint fStencilBits;
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 6ce6089693..2e091871c2 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -34,75 +34,6 @@ static const int SPARE_TEX_UNIT = GrDrawState::kNumStages;
#define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR
#endif
-///////////////////////////////////////////////////////////////////////////////
-
-void GrGpuGL::GLCaps::markConfigAsValidColorAttachment(GrPixelConfig config) {
-#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
- return;
-#endif
- GrAssert(config < kGrPixelConfigCount);
- int u32Idx = config / 32;
- int bitIdx = config % 32;
- fVerifiedColorAttachmentConfigs[u32Idx] |= (1 << bitIdx);
-}
-
-bool GrGpuGL::GLCaps::isConfigVerifiedColorAttachment(
- GrPixelConfig config) const {
-#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
- return false;
-#endif
- GrAssert((unsigned)config < kGrPixelConfigCount);
- int u32Idx = config / 32;
- int bitIdx = config % 32;
- return SkToBool(fVerifiedColorAttachmentConfigs[u32Idx] & (1 << bitIdx));
-}
-
-void GrGpuGL::GLCaps::markColorConfigAndStencilFormatAsVerified(
- GrPixelConfig config,
- const GrGLStencilBuffer::Format& format) {
-#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
- return;
-#endif
- GrAssert((unsigned)config < kGrPixelConfigCount);
- int count = fStencilFormats.count();
- // we expect a really small number of possible formats so linear search
- // should be OK
- GrAssert(count < 16);
- for (int i = 0; i < count; ++i) {
- if (format.fInternalFormat ==
- fStencilFormats[i].fFormat.fInternalFormat) {
- int u32Idx = config / 32;
- int bitIdx = config % 32;
- fStencilFormats[i].fVerifiedColorConfigs[u32Idx] |= (1 << bitIdx);
- return;
- }
- }
- SkDEBUGFAIL("Why are we seeing a stencil format that GLCaps doesn't know about.");
-}
-
-bool GrGpuGL::GLCaps::isColorConfigAndStencilFormatVerified(
- GrPixelConfig config,
- const GrGLStencilBuffer::Format& format) const {
-#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
- return false;
-#endif
- GrAssert((unsigned)config < kGrPixelConfigCount);
- int count = fStencilFormats.count();
- // we expect a really small number of possible formats so linear search
- // should be OK
- GrAssert(count < 16);
- for (int i = 0; i < count; ++i) {
- if (format.fInternalFormat ==
- fStencilFormats[i].fFormat.fInternalFormat) {
- int u32Idx = config / 32;
- int bitIdx = config % 32;
- return SkToBool(fStencilFormats[i].fVerifiedColorConfigs[u32Idx] &
- (1 << bitIdx));
- }
- }
- SkDEBUGFAIL("Why are we seeing a stencil format that GLCaps doesn't know about.");
- return false;
-}
///////////////////////////////////////////////////////////////////////////////
@@ -288,8 +219,6 @@ GrGpuGL::~GrGpuGL() {
///////////////////////////////////////////////////////////////////////////////
-static const GrGLuint kUnknownBitCount = ~0;
-
void GrGpuGL::initCaps() {
GrGLint maxTextureUnits;
// check FS and fixed-function texture unit limits
@@ -302,16 +231,6 @@ void GrGpuGL::initCaps() {
GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_UNITS, &maxTextureUnits);
GrAssert(maxTextureUnits > GrDrawState::kNumStages);
}
- if (kES2_GrGLBinding == this->glBinding()) {
- GR_GL_GetIntegerv(gl, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
- &fGLCaps.fMaxFragmentUniformVectors);
- } else if (kDesktop_GrGLBinding != this->glBinding()) {
- GrGLint max;
- GR_GL_GetIntegerv(gl, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
- fGLCaps.fMaxFragmentUniformVectors = max / 4;
- } else {
- fGLCaps.fMaxFragmentUniformVectors = 16;
- }
GrGLint numFormats;
GR_GL_GetIntegerv(gl, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
@@ -339,51 +258,6 @@ void GrGpuGL::initCaps() {
}
if (kDesktop_GrGLBinding == this->glBinding()) {
- fGLCaps.fRGBA8RenderbufferSupport = true;
- } else {
- fGLCaps.fRGBA8RenderbufferSupport =
- this->hasExtension("GL_OES_rgb8_rgba8") ||
- this->hasExtension("GL_ARM_rgba8");
- }
-
-
- if (kDesktop_GrGLBinding == this->glBinding()) {
- fGLCaps.fBGRAFormatSupport = this->glVersion() >= GR_GL_VER(1,2) ||
- this->hasExtension("GL_EXT_bgra");
- } else {
- bool hasBGRAExt = false;
- if (this->hasExtension("GL_APPLE_texture_format_BGRA8888")) {
- fGLCaps.fBGRAFormatSupport = true;
- } else if (this->hasExtension("GL_EXT_texture_format_BGRA8888")) {
- fGLCaps.fBGRAFormatSupport = true;
- fGLCaps.fBGRAIsInternalFormat = true;
- }
- GrAssert(fGLCaps.fBGRAFormatSupport ||
- kSkia8888_PM_GrPixelConfig != kBGRA_8888_PM_GrPixelConfig);
- }
-
- if (kDesktop_GrGLBinding == this->glBinding()) {
- fGLCaps.fTextureSwizzleSupport = this->glVersion() >= GR_GL_VER(3,3) ||
- this->hasExtension("GL_ARB_texture_swizzle");
- } else {
- fGLCaps.fTextureSwizzleSupport = false;
- }
-
- if (kDesktop_GrGLBinding == this->glBinding()) {
- fGLCaps.fUnpackRowLengthSupport = true;
- fGLCaps.fUnpackFlipYSupport = false;
- fGLCaps.fPackRowLengthSupport = true;
- fGLCaps.fPackFlipYSupport = false;
- } else {
- fGLCaps.fUnpackRowLengthSupport =this->hasExtension("GL_EXT_unpack_subimage");
- fGLCaps.fUnpackFlipYSupport = this->hasExtension("GL_CHROMIUM_flipy");
- // no extension for pack row length
- fGLCaps.fPackRowLengthSupport = false;
- fGLCaps.fPackFlipYSupport =
- this->hasExtension("GL_ANGLE_pack_reverse_row_order");
- }
-
- if (kDesktop_GrGLBinding == this->glBinding()) {
fCaps.fBufferLockSupport = true; // we require VBO support and the desktop VBO
// extension includes glMapBuffer.
} else {
@@ -402,15 +276,6 @@ void GrGpuGL::initCaps() {
fCaps.fNPOTTextureTileSupport = this->hasExtension("GL_OES_texture_npot");
}
- fGLCaps.fTextureUsageSupport = (kES2_GrGLBinding == this->glBinding()) &&
- this->hasExtension("GL_ANGLE_texture_usage");
-
- // Tex storage is in desktop 4.2 and can be an extension to desktop or ES.
- fGLCaps.fTexStorageSupport = (kDesktop_GrGLBinding == this->glBinding() &&
- this->glVersion() >= GR_GL_VER(4,2)) ||
- this->hasExtension("GL_ARB_texture_storage") ||
- this->hasExtension("GL_EXT_texture_storage");
-
fCaps.fHWAALineSupport = (kDesktop_GrGLBinding == this->glBinding());
////////////////////////////////////////////////////////////////////////////
@@ -424,93 +289,7 @@ void GrGpuGL::initCaps() {
// attachment, hence this min:
fCaps.fMaxRenderTargetSize = GrMin(fCaps.fMaxTextureSize, fCaps.fMaxRenderTargetSize);
- this->initFSAASupport();
- this->initStencilFormats();
-}
-
-void GrGpuGL::initFSAASupport() {
-
- fGLCaps.fMSFBOType = GLCaps::kNone_MSFBO;
- if (kDesktop_GrGLBinding != this->glBinding()) {
- if (this->hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
- // chrome's extension is equivalent to the EXT msaa
- // and fbo_blit extensions.
- fGLCaps.fMSFBOType = GLCaps::kDesktopEXT_MSFBO;
- } else if (this->hasExtension("GL_APPLE_framebuffer_multisample")) {
- fGLCaps.fMSFBOType = GLCaps::kAppleES_MSFBO;
- }
- } else {
- if ((this->glVersion() >= GR_GL_VER(3,0)) || this->hasExtension("GL_ARB_framebuffer_object")) {
- fGLCaps.fMSFBOType = GLCaps::kDesktopARB_MSFBO;
- } else if (this->hasExtension("GL_EXT_framebuffer_multisample") &&
- this->hasExtension("GL_EXT_framebuffer_blit")) {
- fGLCaps.fMSFBOType = GLCaps::kDesktopEXT_MSFBO;
- }
- }
-
- fCaps.fFSAASupport = GLCaps::kNone_MSFBO != fGLCaps.fMSFBOType;
-}
-
-void GrGpuGL::initStencilFormats() {
-
- // Build up list of legal stencil formats (though perhaps not supported on
- // the particular gpu/driver) from most preferred to least.
-
- // these consts are in order of most preferred to least preferred
- // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
-
- // Omitting fVerifiedColorConfigs from initializer list should init to 0.
- static const GLCaps::StencilFormat
- // internal Format stencil bits total bits packed?
- gS8 = {{GR_GL_STENCIL_INDEX8, 8, 8, false}, {0U}},
- gS16 = {{GR_GL_STENCIL_INDEX16, 16, 16, false}, {0U}},
- gD24S8 = {{GR_GL_DEPTH24_STENCIL8, 8, 32, true }, {0U}},
- gS4 = {{GR_GL_STENCIL_INDEX4, 4, 4, false}, {0U}},
- gS = {{GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false}, {0U}},
- gDS = {{GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true }, {0U}};
-
- if (kDesktop_GrGLBinding == this->glBinding()) {
- bool supportsPackedDS = this->glVersion() >= GR_GL_VER(3,0) ||
- this->hasExtension("GL_EXT_packed_depth_stencil") ||
- this->hasExtension("GL_ARB_framebuffer_object");
-
- // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
- // require FBO support we can expect these are legal formats and don't
- // check. These also all support the unsized GL_STENCIL_INDEX.
- fGLCaps.fStencilFormats.push_back() = gS8;
- fGLCaps.fStencilFormats.push_back() = gS16;
- if (supportsPackedDS) {
- fGLCaps.fStencilFormats.push_back() = gD24S8;
- }
- fGLCaps.fStencilFormats.push_back() = gS4;
- if (supportsPackedDS) {
- fGLCaps.fStencilFormats.push_back() = gDS;
- }
- } else {
- // ES2 has STENCIL_INDEX8 without extensions but requires extensions
- // for other formats.
- // ES doesn't support using the unsized format.
-
- fGLCaps.fStencilFormats.push_back() = gS8;
- //fStencilFormats.push_back() = gS16;
- if (this->hasExtension("GL_OES_packed_depth_stencil")) {
- fGLCaps.fStencilFormats.push_back() = gD24S8;
- }
- if (this->hasExtension("GL_OES_stencil4")) {
- fGLCaps.fStencilFormats.push_back() = gS4;
- }
- }
-#if GR_DEBUG
- // ensure that initially all color / stencil format combos have unverified
- // fbo status.
- for (int i = 0; i < fGLCaps.fStencilFormats.count(); ++i) {
- int numU32 =
- GR_ARRAY_COUNT(fGLCaps.fStencilFormats[i].fVerifiedColorConfigs);
- for (int j = 0; j < numU32; ++j) {
- GrAssert(0 == fGLCaps.fStencilFormats[i].fVerifiedColorConfigs[j]);
- }
- }
-#endif
+ fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType();
}
GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig config) const {
@@ -537,7 +316,7 @@ void GrGpuGL::onResetContext() {
if (gPrintStartupSpew && !fPrintedCaps) {
fPrintedCaps = true;
this->getCaps().print();
- fGLCaps.print();
+ this->glCaps().print();
}
// We detect cases when blending is effectively off
@@ -607,16 +386,16 @@ void GrGpuGL::onResetContext() {
fHWDrawState.setRenderTarget(NULL);
// we assume these values
- if (this->glCaps().fUnpackRowLengthSupport) {
+ if (this->glCaps().unpackRowLengthSupport()) {
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
}
- if (this->glCaps().fPackRowLengthSupport) {
+ if (this->glCaps().packRowLengthSupport()) {
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
}
- if (this->glCaps().fUnpackFlipYSupport) {
+ if (this->glCaps().unpackFlipYSupport()) {
GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
}
- if (this->glCaps().fPackFlipYSupport) {
+ if (this->glCaps().packFlipYSupport()) {
GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
}
}
@@ -766,7 +545,7 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
SkAutoSMalloc<128 * 128> tempStorage;
bool useTexStorage = isNewTexture &&
- this->glCaps().fTexStorageSupport;
+ this->glCaps().texStorageSupport();
if (useTexStorage) {
if (kDesktop_GrGLBinding == this->glBinding()) {
// 565 is not a sized internal format on desktop GL. So on desktop
@@ -807,13 +586,13 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
bool glFlipY = false;
if (NULL != data) {
if (GrGLTexture::kBottomUp_Orientation == desc.fOrientation) {
- if (this->glCaps().fUnpackFlipYSupport) {
+ if (this->glCaps().unpackFlipYSupport()) {
glFlipY = true;
} else {
swFlipY = true;
}
}
- if (this->glCaps().fUnpackRowLengthSupport && !swFlipY) {
+ if (this->glCaps().unpackRowLengthSupport() && !swFlipY) {
// can't use this for flipping, only non-neg values allowed. :(
if (rowBytes != trimRowBytes) {
GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
@@ -910,7 +689,7 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
}
if (restoreGLRowLength) {
- GrAssert(this->glCaps().fUnpackRowLengthSupport);
+ GrAssert(this->glCaps().unpackRowLengthSupport());
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
}
if (glFlipY) {
@@ -941,7 +720,7 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
// If we are using multisampling we will create two FBOS. We render
// to one and then resolve to the texture bound to the other.
if (desc->fSampleCnt > 0) {
- if (GLCaps::kNone_MSFBO == fGLCaps.fMSFBOType) {
+ if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
goto FAILED;
}
GL_CALL(GenFramebuffers(1, &desc->fRTFBOID));
@@ -979,12 +758,13 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
GR_GL_COLOR_ATTACHMENT0,
GR_GL_RENDERBUFFER,
desc->fMSColorRenderbufferID));
- if (!fGLCaps.isConfigVerifiedColorAttachment(desc->fConfig)) {
+ if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
goto FAILED;
}
- fGLCaps.markConfigAsValidColorAttachment(desc->fConfig);
+ fGLContextInfo.caps().markConfigAsValidColorAttachment(
+ desc->fConfig);
}
}
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
@@ -993,12 +773,12 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
GR_GL_COLOR_ATTACHMENT0,
GR_GL_TEXTURE_2D,
texID, 0));
- if (!fGLCaps.isConfigVerifiedColorAttachment(desc->fConfig)) {
+ if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
goto FAILED;
}
- fGLCaps.markConfigAsValidColorAttachment(desc->fConfig);
+ fGLContextInfo.caps().markConfigAsValidColorAttachment(desc->fConfig);
}
return true;
@@ -1064,7 +844,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GrGLTexture::kTopDown_Orientation;
glRTDesc.fSampleCnt = desc.fSampleCnt;
- if (GLCaps::kNone_MSFBO == fGLCaps.fMSFBOType &&
+ if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&
desc.fSampleCnt) {
GrPrintf("MSAA RT requested but not supported on this platform.");
}
@@ -1077,7 +857,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
}
GL_CALL(GenTextures(1, &glTexDesc.fTextureID));
- if (renderTarget && this->glCaps().fTextureUsageSupport) {
+ if (renderTarget && this->glCaps().textureUsageSupport()) {
// provides a hint about how this texture will be used
GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
GR_GL_TEXTURE_USAGE,
@@ -1143,6 +923,9 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
}
namespace {
+
+const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
+
void inline get_stencil_rb_sizes(const GrGLInterface* gl,
GrGLuint rb,
GrGLStencilBuffer::Format* format) {
@@ -1183,14 +966,15 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
GrGLStencilBuffer* sb = NULL;
- int stencilFmtCnt = fGLCaps.fStencilFormats.count();
+ int stencilFmtCnt = this->glCaps().stencilFormats().count();
for (int i = 0; i < stencilFmtCnt; ++i) {
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID));
// we start with the last stencil format that succeeded in hopes
// that we won't go through this loop more than once after the
// first (painful) stencil creation.
int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
- const GLCaps::StencilFormat& sFmt = fGLCaps.fStencilFormats[sIdx];
+ const GrGLCaps::StencilFormat& sFmt =
+ this->glCaps().stencilFormats()[sIdx];
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
// we do this "if" so that we don't call the multisample
// version on a GL that doesn't have an MSAA extension.
@@ -1198,12 +982,12 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
GL_ALLOC_CALL(this->glInterface(),
RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
samples,
- sFmt.fFormat.fInternalFormat,
+ sFmt.fInternalFormat,
width, height));
} else {
GL_ALLOC_CALL(this->glInterface(),
RenderbufferStorage(GR_GL_RENDERBUFFER,
- sFmt.fFormat.fInternalFormat,
+ sFmt.fInternalFormat,
width, height));
}
@@ -1211,7 +995,7 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
if (err == GR_GL_NO_ERROR) {
// After sized formats we attempt an unsized format and take whatever
// sizes GL gives us. In that case we query for the size.
- GrGLStencilBuffer::Format format = sFmt.fFormat;
+ GrGLStencilBuffer::Format format = sFmt;
get_stencil_rb_sizes(this->glInterface(), sbID, &format);
sb = new GrGLStencilBuffer(this, sbID, width, height,
samples, format);
@@ -1270,7 +1054,7 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
}
GrGLenum status;
- if (!fGLCaps.isColorConfigAndStencilFormatVerified(rt->config(),
+ if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
glsb->format())) {
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
@@ -1284,7 +1068,7 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
}
return false;
} else {
- fGLCaps.markColorConfigAndStencilFormatAsVerified(
+ fGLContextInfo.caps().markColorConfigAndStencilFormatAsVerified(
rt->config(),
glsb->format());
}
@@ -1482,13 +1266,13 @@ bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
GrPixelConfig config,
size_t rowBytes) const {
// if GL can do the flip then we'll never pay for it.
- if (this->glCaps().fPackFlipYSupport) {
+ if (this->glCaps().packFlipYSupport()) {
return false;
}
// If we have to do memcpy to handle non-trim rowBytes then we
// get the flip for free. Otherwise it costs.
- if (this->glCaps().fPackRowLengthSupport) {
+ if (this->glCaps().packRowLengthSupport()) {
return true;
}
// If we have to do memcpys to handle rowBytes then y-flip is free
@@ -1559,7 +1343,7 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
// a scratch buffer.
SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
if (rowBytes != tightRowBytes) {
- if (this->glCaps().fPackRowLengthSupport) {
+ if (this->glCaps().packRowLengthSupport()) {
GrAssert(!(rowBytes % sizeof(GrColor)));
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowBytes / sizeof(GrColor)));
readDstRowBytes = rowBytes;
@@ -1568,17 +1352,17 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
readDst = scratch.get();
}
}
- if (!invertY && this->glCaps().fPackFlipYSupport) {
+ if (!invertY && this->glCaps().packFlipYSupport()) {
GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1));
}
GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
readRect.fWidth, readRect.fHeight,
format, type, readDst));
if (readDstRowBytes != tightRowBytes) {
- GrAssert(this->glCaps().fPackRowLengthSupport);
+ GrAssert(this->glCaps().packRowLengthSupport());
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
}
- if (!invertY && this->glCaps().fPackFlipYSupport) {
+ if (!invertY && this->glCaps().packFlipYSupport()) {
GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0));
invertY = true;
}
@@ -1752,7 +1536,7 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
if (rt->needsResolve()) {
- GrAssert(GLCaps::kNone_MSFBO != fGLCaps.fMSFBOType);
+ GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType());
GrAssert(rt->textureFBOID() != rt->renderFBOID());
GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
rt->renderFBOID()));
@@ -1770,7 +1554,7 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
dirtyRect.width(), dirtyRect.height());
- if (GLCaps::kAppleES_MSFBO == fGLCaps.fMSFBOType) {
+ if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
// Apple's extension uses the scissor as the blit bounds.
GL_CALL(Enable(GR_GL_SCISSOR_TEST));
GL_CALL(Scissor(r.fLeft, r.fBottom,
@@ -1779,9 +1563,10 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
fHWBounds.fScissorRect.invalidate();
fHWBounds.fScissorEnabled = true;
} else {
- if (GLCaps::kDesktopARB_MSFBO != fGLCaps.fMSFBOType) {
+ if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
// this respects the scissor during the blit, so disable it.
- GrAssert(GLCaps::kDesktopEXT_MSFBO == fGLCaps.fMSFBOType);
+ GrAssert(GrGLCaps::kDesktopEXT_MSFBOType ==
+ this->glCaps().msFBOType());
this->flushScissor(NULL);
}
int right = r.fLeft + r.fWidth;
@@ -2185,7 +1970,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
GR_GL_TEXTURE_WRAP_T,
newTexParams.fWrapT));
}
- if (this->glCaps().fTextureSwizzleSupport &&
+ if (this->glCaps().textureSwizzleSupport() &&
(setAll ||
memcmp(newTexParams.fSwizzleRGBA,
oldTexParams.fSwizzleRGBA,
@@ -2347,10 +2132,10 @@ bool GrGpuGL::configToGLFormats(GrPixelConfig config,
break;
case kBGRA_8888_PM_GrPixelConfig:
case kBGRA_8888_UPM_GrPixelConfig:
- if (!fGLCaps.fBGRAFormatSupport) {
+ if (!this->glCaps().bgraFormatSupport()) {
return false;
}
- if (fGLCaps.fBGRAIsInternalFormat) {
+ if (this->glCaps().bgraIsInternalFormat()) {
if (getSizedInternalFormat) {
*internalFormat = GR_GL_BGRA8;
} else {
@@ -2503,42 +2288,7 @@ void GrGpuGL::setBuffers(bool indexed,
int GrGpuGL::getMaxEdges() const {
// FIXME: This is a pessimistic estimate based on how many other things
// want to add uniforms. This should be centralized somewhere.
- return GR_CT_MIN(fGLCaps.fMaxFragmentUniformVectors - 8,
+ return GR_CT_MIN(this->glCaps().maxFragmentUniformVectors() - 8,
GrDrawState::kMaxEdges);
}
-void GrGpuGL::GLCaps::print() const {
- for (int i = 0; i < fStencilFormats.count(); ++i) {
- GrPrintf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
- i,
- fStencilFormats[i].fFormat.fStencilBits,
- fStencilFormats[i].fFormat.fTotalBits);
- }
-
- GR_STATIC_ASSERT(0 == kNone_MSFBO);
- GR_STATIC_ASSERT(1 == kDesktopARB_MSFBO);
- GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBO);
- GR_STATIC_ASSERT(3 == kAppleES_MSFBO);
- static const char* gMSFBOExtStr[] = {
- "None",
- "ARB",
- "EXT",
- "Apple",
- };
- GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
- GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
- GrPrintf("Support RGBA8 Render Buffer: %s\n",
- (fRGBA8RenderbufferSupport ? "YES": "NO"));
- GrPrintf("BGRA is an internal format: %s\n",
- (fBGRAIsInternalFormat ? "YES": "NO"));
- GrPrintf("Support texture swizzle: %s\n",
- (fTextureSwizzleSupport ? "YES": "NO"));
- GrPrintf("Unpack Row length support: %s\n",
- (fUnpackRowLengthSupport ? "YES": "NO"));
- GrPrintf("Unpack Flip Y support: %s\n",
- (fUnpackFlipYSupport ? "YES": "NO"));
- GrPrintf("Pack Row length support: %s\n",
- (fPackRowLengthSupport ? "YES": "NO"));
- GrPrintf("Pack Flip Y support: %s\n",
- (fPackFlipYSupport ? "YES": "NO"));
-}
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index b3e5060b30..eac8d4f502 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -49,116 +49,6 @@ public:
protected:
GrGpuGL(const GrGLContextInfo& ctxInfo);
- struct GLCaps {
- GLCaps()
- // make defaults be the most restrictive
- : fStencilFormats(8) // prealloc space for stencil formats
- , fMSFBOType(kNone_MSFBO)
- , fMaxFragmentUniformVectors(0)
- , fRGBA8RenderbufferSupport(false)
- , fBGRAFormatSupport(false)
- , fBGRAIsInternalFormat(false)
- , fTextureSwizzleSupport(false)
- , fUnpackRowLengthSupport(false)
- , fUnpackFlipYSupport(false)
- , fPackRowLengthSupport(false)
- , fPackFlipYSupport(false)
- , fTextureUsageSupport(false)
- , fTexStorageSupport(false) {
- memset(&fVerifiedColorAttachmentConfigs, 0,
- sizeof(fVerifiedColorAttachmentConfigs));
- }
-
- // Call to note that a color config has been verified as a valid
- // color attachment. This may save future calls to
- // CheckFramebufferStatus
- void markConfigAsValidColorAttachment(GrPixelConfig config);
-
- // Call to check whether a config has been verified as a valid color
- // attachment.
- bool isConfigVerifiedColorAttachment(GrPixelConfig config) const;
-
- // Call to note that a color config / stencil format pair passed
- // FBO status check. We may skip calling CheckFramebufferStatus for
- // this combination in the future.
- void markColorConfigAndStencilFormatAsVerified(
- GrPixelConfig config,
- const GrGLStencilBuffer::Format& format);
-
- // Call to check whether color config / stencil format pair has already
- // passed FBO status check.
- bool isColorConfigAndStencilFormatVerified(
- GrPixelConfig config,
- const GrGLStencilBuffer::Format& format) const;
-
- void print() const;
-
- struct StencilFormat {
- GrGLStencilBuffer::Format fFormat;
- uint32_t fVerifiedColorConfigs[(kGrPixelConfigCount + 31) / 32];
- };
-
- SkTArray<StencilFormat, true> fStencilFormats;
-
-
- enum {
- /**
- * no support for MSAA FBOs
- */
- kNone_MSFBO = 0,
- /**
- * GL3.0-style MSAA FBO (GL_ARB_framebuffer_object)
- */
- kDesktopARB_MSFBO,
- /**
- * earlier GL_EXT_framebuffer* extensions
- */
- kDesktopEXT_MSFBO,
- /**
- * GL_APPLE_framebuffer_multisample ES extension
- */
- kAppleES_MSFBO,
- } fMSFBOType;
-
- // The maximum number of fragment uniform vectors (GLES has min. 16).
- int fMaxFragmentUniformVectors;
-
- // ES requires an extension to support RGBA8 in RenderBufferStorage
- bool fRGBA8RenderbufferSupport;
-
- // Is GL_BGRA supported
- bool fBGRAFormatSupport;
-
- // Depending on the ES extensions present the BGRA external format may
- // correspond either a BGRA or RGBA internalFormat. On desktop GL it is
- // RGBA
- bool fBGRAIsInternalFormat;
-
- // GL_ARB_texture_swizzle support
- bool fTextureSwizzleSupport;
-
- // Is there support for GL_UNPACK_ROW_LENGTH
- bool fUnpackRowLengthSupport;
-
- // Is there support for GL_UNPACK_FLIP_Y
- bool fUnpackFlipYSupport;
-
- // Is there support for GL_PACK_ROW_LENGTH
- bool fPackRowLengthSupport;
-
- // Is there support for GL_PACK_REVERSE_ROW_ORDER
- bool fPackFlipYSupport;
-
- // Is there support for texture parameter GL_TEXTURE_USAGE
- bool fTextureUsageSupport;
-
- // Is there support for glTexStorage
- bool fTexStorageSupport;
-
- private:
- uint32_t fVerifiedColorAttachmentConfigs[(kGrPixelConfigCount + 31) / 32];
- } fGLCaps;
-
struct {
size_t fVertexOffset;
GrVertexLayout fVertexLayout;
@@ -196,7 +86,7 @@ protected:
GrGLIRect fViewportRect;
} fHWBounds;
- const GLCaps& glCaps() const { return fGLCaps; }
+ const GrGLCaps& glCaps() const { return fGLContextInfo.caps(); }
// GrGpu overrides
virtual void onResetContext() SK_OVERRIDE;
@@ -294,8 +184,7 @@ protected:
static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
private:
- // Inits GrDrawTarget::Caps and GLCaps, sublcass may enable
- // additional caps.
+ // Inits GrDrawTarget::Caps, sublcass may enable additional caps.
void initCaps();
void initFSAASupport();
diff --git a/src/gpu/gl/GrGpuGLShaders.cpp b/src/gpu/gl/GrGpuGLShaders.cpp
index 7fe7d4bd58..4093a0da0d 100644
--- a/src/gpu/gl/GrGpuGLShaders.cpp
+++ b/src/gpu/gl/GrGpuGLShaders.cpp
@@ -1091,7 +1091,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
}
stage.fInConfigFlags = 0;
- if (!this->glCaps().fTextureSwizzleSupport) {
+ if (!this->glCaps().textureSwizzleSupport()) {
if (GrPixelConfigIsAlphaOnly(texture->config())) {
// if we don't have texture swizzle support then
// the shader must do an alpha smear after reading