aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-05 23:29:25 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-05 23:29:25 +0000
commita15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11ac (patch)
tree5e7ada52ebeedc3850364b15ee8f99b58233f220 /src/gpu/gl
parentf51e125b949fdda350256c7132ee54c49ea53519 (diff)
Use all available texture units.
R=robertphillips@google.com, jvanverth@google.com Author: bsalomon@google.com Review URL: https://chromiumcodereview.appspot.com/16452007 git-svn-id: http://skia.googlecode.com/svn/trunk@9451 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLCaps.cpp9
-rw-r--r--src/gpu/gl/GrGLCaps.h6
-rw-r--r--src/gpu/gl/GrGpuGL.cpp65
-rw-r--r--src/gpu/gl/GrGpuGL.h6
4 files changed, 30 insertions, 56 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 8b296e360b..fd74d50d71 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -28,6 +28,7 @@ void GrGLCaps::reset() {
fFBFetchType = kNone_FBFetchType;
fMaxFragmentUniformVectors = 0;
fMaxVertexAttributes = 0;
+ fMaxFragmentTextureUnits = 0;
fRGBA8RenderbufferSupport = false;
fBGRAFormatSupport = false;
fBGRAIsInternalFormat = false;
@@ -59,6 +60,7 @@ GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs;
fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors;
fMaxVertexAttributes = caps.fMaxVertexAttributes;
+ fMaxFragmentTextureUnits = caps.fMaxFragmentTextureUnits;
fMSFBOType = caps.fMSFBOType;
fCoverageAAType = caps.fCoverageAAType;
fMSAACoverageModes = caps.fMSAACoverageModes;
@@ -109,6 +111,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
fMaxFragmentUniformVectors = max / 4;
}
GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
+ GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits);
if (kDesktop_GrGLBinding == binding) {
fRGBA8RenderbufferSupport = true;
@@ -222,12 +225,6 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
/**************************************************************************
* GrDrawTargetCaps fields
**************************************************************************/
- GrGLint maxTextureUnits;
- // check FS and fixed-function texture unit limits
- // we only use textures in the fragment stage currently.
- // checks are > to make sure we have a spare unit.
- GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
-
GrGLint numFormats;
GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
if (numFormats) {
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 01fbceee04..0b625a5a3a 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -215,9 +215,12 @@ public:
/// The maximum number of fragment uniform vectors (GLES has min. 16).
int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
- // maximum number of attribute values per vertex
+ /// maximum number of attribute values per vertex
int maxVertexAttributes() const { return fMaxVertexAttributes; }
+ /// maximum number of texture units accessible in the fragment shader.
+ int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; }
+
/// ES requires an extension to support RGBA8 in RenderBufferStorage
bool rgba8RenderbufferSupport() const { return fRGBA8RenderbufferSupport; }
@@ -332,6 +335,7 @@ private:
int fMaxFragmentUniformVectors;
int fMaxVertexAttributes;
+ int fMaxFragmentTextureUnits;
MSFBOType fMSFBOType;
CoverageAAType fCoverageAAType;
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 0c47060e4f..2f218a0c86 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -20,9 +20,6 @@ static const GrGLint GR_INVAL_GLINT = ~0;
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
-// we use a spare texture unit to avoid
-// mucking with the state of any of the stages.
-static const int SPARE_TEX_UNIT = GrDrawState::kNumStages;
#define SKIP_CACHE_CHECK true
@@ -118,35 +115,6 @@ bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) {
static bool gPrintStartupSpew;
-static bool fbo_test(const GrGLInterface* gl, int w, int h) {
-
- GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT));
-
- GrGLuint testFBO;
- GR_GL_CALL(gl, GenFramebuffers(1, &testFBO));
- GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, testFBO));
- GrGLuint testRTTex;
- GR_GL_CALL(gl, GenTextures(1, &testRTTex));
- GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, testRTTex));
- // some implementations require texture to be mip-map complete before
- // FBO with level 0 bound as color attachment will be framebuffer complete.
- GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
- GR_GL_TEXTURE_MIN_FILTER,
- GR_GL_NEAREST));
- GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D, 0, GR_GL_RGBA, w, h,
- 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, NULL));
- GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
- GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
- GR_GL_COLOR_ATTACHMENT0,
- GR_GL_TEXTURE_2D, testRTTex, 0));
- GrGLenum status;
- GR_GL_CALL_RET(gl, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
- GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO));
- GR_GL_CALL(gl, DeleteTextures(1, &testRTTex));
-
- return status == GR_GL_FRAMEBUFFER_COMPLETE;
-}
-
GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
: GrGpu(context)
, fGLContext(ctx) {
@@ -155,6 +123,8 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
fCaps.reset(SkRef(ctx.info().caps()));
+ fHWBoundTextures.reset(ctx.info().caps()->maxFragmentTextureUnits());
+
fillInConfigRenderableTable();
@@ -183,9 +153,6 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
GrAssert(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt);
fLastSuccessfulStencilFmtIdx = 0;
- if (false) { // avoid bit rot, suppress warning
- fbo_test(this->glInterface(), 0, 0);
- }
}
GrGpuGL::~GrGpuGL() {
@@ -361,7 +328,7 @@ void GrGpuGL::onResetContext() {
fHWBlendState.invalidate();
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ for (int s = 0; s < fHWBoundTextures.count(); ++s) {
fHWBoundTextures[s] = NULL;
}
@@ -473,7 +440,6 @@ GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) {
return NULL;
}
- this->setSpareTextureUnit();
return texture;
}
@@ -527,7 +493,7 @@ bool GrGpuGL::onWriteTexturePixels(GrTexture* texture,
}
GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
- this->setSpareTextureUnit();
+ this->setScratchTextureUnit();
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
GrGLTexture::Desc desc;
desc.fFlags = glTex->desc().fFlags;
@@ -952,7 +918,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
return return_null_texture();
}
- this->setSpareTextureUnit();
+ this->setScratchTextureUnit();
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
// Some drivers like to know filter/wrap before seeing glTexImage2D. Some
@@ -2102,7 +2068,7 @@ void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
}
void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ for (int s = 0; s < fHWBoundTextures.count(); ++s) {
if (fHWBoundTextures[s] == texture) {
// deleting bound texture does implied bind to 0
fHWBoundTextures[s] = NULL;
@@ -2222,18 +2188,23 @@ bool GrGpuGL::configToGLFormats(GrPixelConfig config,
}
void GrGpuGL::setTextureUnit(int unit) {
- GrAssert(unit >= 0 && unit < GrDrawState::kNumStages);
- if (fHWActiveTextureUnitIdx != unit) {
+ GrAssert(unit >= 0 && unit < fHWBoundTextures.count());
+ if (unit != fHWActiveTextureUnitIdx) {
GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
fHWActiveTextureUnitIdx = unit;
}
}
-void GrGpuGL::setSpareTextureUnit() {
- if (fHWActiveTextureUnitIdx != (GR_GL_TEXTURE0 + SPARE_TEX_UNIT)) {
- GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT));
- fHWActiveTextureUnitIdx = SPARE_TEX_UNIT;
+void GrGpuGL::setScratchTextureUnit() {
+ // Bind the last texture unit since it is the least likely to be used by GrGLProgram.
+ int lastUnitIdx = fHWBoundTextures.count() - 1;
+ if (lastUnitIdx != fHWActiveTextureUnitIdx) {
+ GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx));
+ fHWActiveTextureUnitIdx = lastUnitIdx;
}
+ // clear out the this field so that if a program does use this unit it will rebind the correct
+ // texture.
+ fHWBoundTextures[lastUnitIdx] = NULL;
}
namespace {
@@ -2370,7 +2341,7 @@ bool GrGpuGL::onCopySurface(GrSurface* dst,
srcRect.height(),
src->origin());
- this->setSpareTextureUnit();
+ this->setScratchTextureUnit();
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID()));
GrGLint dstY;
if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 094fca1f1b..85cace71fb 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -227,7 +227,9 @@ private:
// determines valid stencil formats
void initStencilFormats();
- void setSpareTextureUnit();
+ // sets a texture unit to use for texture operations other than binding a texture to a program.
+ // ensures that such operations don't negatively interact with tracking bound textures.
+ void setScratchTextureUnit();
// bound is region that may be modified and therefore has to be resolved.
// NULL means whole target. Can be an empty rect.
@@ -425,7 +427,7 @@ private:
TriState fHWWriteToColor;
TriState fHWDitherEnabled;
GrRenderTarget* fHWBoundRenderTarget;
- GrTexture* fHWBoundTextures[GrDrawState::kNumStages];
+ SkTArray<GrTexture*, true> fHWBoundTextures;
///@}
// we record what stencil format worked last time to hopefully exit early