aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-13 17:58:13 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-13 17:58:13 +0000
commit919583674bd5daeb60327c0bc1ce8aaa80d54e13 (patch)
tree9f1995df1f0cb6eff01c94445e96e60fcd32e59b /gpu
parente32b5837c3f35b80502759f3de3e8cadf6625f4e (diff)
Consider hw render target limit for offscreen supersample and tile
Review URL: http://codereview.appspot.com/4575041/ git-svn-id: http://skia.googlecode.com/svn/trunk@1568 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu')
-rw-r--r--gpu/include/GrConfig.h16
-rw-r--r--gpu/include/GrContext.h34
-rw-r--r--gpu/include/GrContext_impl.h35
-rw-r--r--gpu/include/GrGpu.h12
-rw-r--r--gpu/include/GrTypes.h4
-rw-r--r--gpu/src/GrContext.cpp192
-rw-r--r--gpu/src/GrGpuGL.cpp28
7 files changed, 198 insertions, 123 deletions
diff --git a/gpu/include/GrConfig.h b/gpu/include/GrConfig.h
index 9ee37c73cc..b3025f389d 100644
--- a/gpu/include/GrConfig.h
+++ b/gpu/include/GrConfig.h
@@ -371,6 +371,22 @@ inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
#define GR_GEOM_BUFFER_LOCK_THRESHOLD (1 << 15)
#endif
+/**
+ * Enables/disables use of offscreen AA
+ */
+#if !defined(GR_USE_OFFSCREEN_AA)
+ #define GR_USE_OFFSCREEN_AA 1
+#endif
+
+/**
+ * GR_MAX_OFFSCREEN_AA_SIZE controls the size at which offscreen AA will tile.
+ * Tiling saves GPU memory by limiting the size of the offscreen buffer. The
+ * max offscreen may be as large as (4*GR_MAX_OFFSCREEN_AA_SIZE)^2 pixels.
+ */
+#if !defined(GR_MAX_OFFSCREEN_AA_SIZE)
+ #define GR_MAX_OFFSCREEN_AA_SIZE 256
+#endif
+
///////////////////////////////////////////////////////////////////////////////
// tail section:
//
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 8809271e80..5dfe2c998e 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -158,7 +158,13 @@ public:
/**
* Return the max width or height of a texture supported by the current gpu
*/
- int getMaxTextureDimension();
+ int getMaxTextureSize() const;
+
+ /**
+ * Return the max width or height of a render target supported by the
+ * current gpu
+ */
+ int getMaxRenderTargetSize() const;
///////////////////////////////////////////////////////////////////////////
// Render targets
@@ -399,7 +405,6 @@ public:
const TEX_SRC* texCoordSrc,
const COL_SRC* colorSrc);
-
///////////////////////////////////////////////////////////////////////////
// Misc.
@@ -532,6 +537,7 @@ private:
GrIndexBuffer* fAAFillRectIndexBuffer;
GrIndexBuffer* fAAStrokeRectIndexBuffer;
+ int fMaxOffscreenAASize;
GrContext(GrGpu* gpu);
@@ -568,22 +574,34 @@ private:
struct OffscreenRecord;
+ // determines whether offscreen AA should be applied
bool doOffscreenAA(GrDrawTarget* target,
const GrPaint& paint,
bool isLines) const;
- // sets up target to draw coverage to the supersampled render target
- bool setupOffscreenAAPass1(GrDrawTarget* target,
+ // attempts to setup offscreen AA. All paint state must be transferred to
+ // target by the time this is called.
+ bool prepareForOffscreenAA(GrDrawTarget* target,
bool requireStencil,
const GrIRect& boundRect,
OffscreenRecord* record);
+ // sets up target to draw coverage to the supersampled render target
+ void setupOffscreenAAPass1(GrDrawTarget* target,
+ const GrIRect& boundRect,
+ int tileX, int tileY,
+ OffscreenRecord* record);
+
// sets up target to sample coverage of supersampled render target back
// to the main render target using stage kOffscreenStage.
- void offscreenAAPass2(GrDrawTarget* target,
- const GrPaint& paint,
- const GrIRect& boundRect,
- OffscreenRecord* record);
+ void doOffscreenAAPass2(GrDrawTarget* target,
+ const GrPaint& paint,
+ const GrIRect& boundRect,
+ int tileX, int tileY,
+ OffscreenRecord* record);
+
+ // restored the draw target state and releases offscreen target to cache
+ void cleanupOffscreenAA(GrDrawTarget* target, OffscreenRecord* record);
// computes vertex layout bits based on the paint. If paint expresses
// a texture for a stage, the stage coords will be bound to postitions
diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h
index c79a191e2f..b33d0b4d4f 100644
--- a/gpu/include/GrContext_impl.h
+++ b/gpu/include/GrContext_impl.h
@@ -17,20 +17,6 @@
#ifndef GrContext_impl_DEFINED
#define GrContext_impl_DEFINED
-struct GrContext::OffscreenRecord {
- OffscreenRecord() { fEntry0 = NULL; fEntry1 = NULL; }
- ~OffscreenRecord() { GrAssert(NULL == fEntry0 && NULL == fEntry1); }
-
- enum Downsample {
- k4x4TwoPass_Downsample,
- k4x4SinglePass_Downsample,
- kFSAA_Downsample
- } fDownsample;
- GrTextureEntry* fEntry0;
- GrTextureEntry* fEntry1;
- GrDrawTarget::SavedDrawState fSavedState;
-};
-
template <typename POS_SRC, typename TEX_SRC,
typename COL_SRC, typename IDX_SRC>
inline void GrContext::drawCustomVertices(const GrPaint& paint,
@@ -86,31 +72,14 @@ inline void GrContext::drawCustomVertices(const GrPaint& paint,
idxSrc->writeValue(i, indices + i);
}
- bool doAA = false;
- OffscreenRecord record;
- GrIRect bounds;
-
- if (-1 == texOffsets[0] && -1 == colorOffset &&
- this->doOffscreenAA(target, paint, GrIsPrimTypeLines(primitiveType))) {
- GrRect b;
- b.setBounds(geo.positions(), vertexCount);
- target->getViewMatrix().mapRect(&b);
- b.roundOut(&bounds);
- if (this->setupOffscreenAAPass1(target, false, bounds, &record)) {
- doAA = true;
- }
- }
+ // we don't currently apply offscreen AA to this path. Need improved
+ // management of GrDrawTarget's geometry to avoid copying points per-tile.
if (NULL == idxSrc) {
target->drawNonIndexed(primitiveType, 0, vertexCount);
} else {
target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
}
-
- if (doAA) {
- geo.set(NULL, 0, 0, 0); // have to release geom before can draw again
- this->offscreenAAPass2(target, paint, bounds, &record);
- }
}
class GrNullTexCoordSource {
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 5cb885a7ef..34ddccf517 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -253,7 +253,14 @@ public:
*/
bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
- int maxTextureDimension() const { return fMaxTextureDimension; }
+ /**
+ * Gets the largest allowed width and height of a texture.
+ */
+ int maxTextureSize() const { return fMaxTextureSize; }
+ /**
+ * Gets the largest allowed width and height of a render target.
+ */
+ int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
// GrDrawTarget overrides
virtual void drawIndexed(GrPrimitiveType type,
@@ -404,7 +411,8 @@ protected:
// set by subclass
int fMinRenderTargetWidth;
int fMinRenderTargetHeight;
- int fMaxTextureDimension;
+ int fMaxRenderTargetSize;
+ int fMaxTextureSize;
GrGpuStats fStats;
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
index 9348375987..e6f3e2c3de 100644
--- a/gpu/include/GrTypes.h
+++ b/gpu/include/GrTypes.h
@@ -69,6 +69,10 @@ template <typename T> const T& GrMax(const T& a, const T& b) {
/**
* divide, rounding up
*/
+static inline int32_t GrIDivRoundUp(int x, int y) {
+ GrAssert(y > 0);
+ return (x + (y-1)) / y;
+}
static inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
return (x + (y-1)) / y;
}
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 4ebf225a3c..773c5738d1 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -25,10 +25,9 @@
#include "GrBufferAllocPool.h"
#include "GrPathRenderer.h"
-// larger than this, and we don't AA. set to 0 for no AA
-#ifndef GR_MAX_OFFSCREEN_AA_DIM
- #define GR_MAX_OFFSCREEN_AA_DIM 0
-#endif
+// Using MSAA seems to be slower for some yet unknown reason.
+#define PREFER_MSAA_OFFSCREEN_AA 0
+#define OFFSCREEN_SSAA_SCALE 4 // super sample at 4x4
#define DEFER_TEXT_RENDERING 1
@@ -361,8 +360,12 @@ void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
fTextureCache->setLimits(maxTextures, maxTextureBytes);
}
-int GrContext::getMaxTextureDimension() {
- return fGpu->maxTextureDimension();
+int GrContext::getMaxTextureSize() const {
+ return fGpu->maxTextureSize();
+}
+
+int GrContext::getMaxRenderTargetSize() const {
+ return fGpu->maxRenderTargetSize();
}
///////////////////////////////////////////////////////////////////////////////
@@ -454,10 +457,28 @@ void GrContext::drawPaint(const GrPaint& paint) {
////////////////////////////////////////////////////////////////////////////////
+struct GrContext::OffscreenRecord {
+ OffscreenRecord() { fEntry0 = NULL; fEntry1 = NULL; }
+ ~OffscreenRecord() { GrAssert(NULL == fEntry0 && NULL == fEntry1); }
+
+ enum Downsample {
+ k4x4TwoPass_Downsample,
+ k4x4SinglePass_Downsample,
+ kFSAA_Downsample
+ } fDownsample;
+ int fTileSize;
+ int fTileCountX;
+ int fTileCountY;
+ int fScale;
+ GrTextureEntry* fEntry0;
+ GrTextureEntry* fEntry1;
+ GrDrawTarget::SavedDrawState fSavedState;
+};
+
bool GrContext::doOffscreenAA(GrDrawTarget* target,
const GrPaint& paint,
bool isLines) const {
-#if GR_MAX_OFFSCREEN_AA_DIM==0
+#if !GR_USE_OFFSCREEN_AA
return false;
#else
if (!paint.fAntiAlias) {
@@ -483,18 +504,26 @@ bool GrContext::doOffscreenAA(GrDrawTarget* target,
#endif
}
-bool GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
+bool GrContext::prepareForOffscreenAA(GrDrawTarget* target,
bool requireStencil,
const GrIRect& boundRect,
OffscreenRecord* record) {
- GrAssert(GR_MAX_OFFSCREEN_AA_DIM > 0);
+
+ GrAssert(GR_USE_OFFSCREEN_AA);
GrAssert(NULL == record->fEntry0);
GrAssert(NULL == record->fEntry1);
+ GrAssert(!boundRect.isEmpty());
int boundW = boundRect.width();
int boundH = boundRect.height();
- int size = GrMax(64, (int)GrNextPow2(GrMax(boundW, boundH)));
+
+ record->fTileSize = (int)GrNextPow2(GrMax(boundW, boundH));
+ record->fTileSize = GrMax(64, record->fTileSize);
+ record->fTileSize = GrMin(fMaxOffscreenAASize, record->fTileSize);
+
+ record->fTileCountX = GrIDivRoundUp(boundW, record->fTileSize);
+ record->fTileCountY = GrIDivRoundUp(boundH, record->fTileSize);
GrTextureDesc desc;
if (requireStencil) {
@@ -506,22 +535,22 @@ bool GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
desc.fFormat = kRGBA_8888_GrPixelConfig;
- int scale;
- // Using MSAA seems to be slower for some yet unknown reason.
- if (false && fGpu->supportsFullsceneAA()) {
+ if (PREFER_MSAA_OFFSCREEN_AA && fGpu->supportsFullsceneAA()) {
record->fDownsample = OffscreenRecord::kFSAA_Downsample;
- scale = GR_Scalar1;
+ record->fScale = GR_Scalar1;
desc.fAALevel = kMed_GrAALevel;
} else {
record->fDownsample = (fGpu->supports4x4DownsampleFilter()) ?
OffscreenRecord::k4x4SinglePass_Downsample :
OffscreenRecord::k4x4TwoPass_Downsample;
- scale = 4;
+ record->fScale = OFFSCREEN_SSAA_SCALE;
+ // both downsample paths assume this
+ GR_STATIC_ASSERT(4 == OFFSCREEN_SSAA_SCALE);
desc.fAALevel = kNone_GrAALevel;
}
- desc.fWidth = scale * size;
- desc.fHeight = scale * size;
+ desc.fWidth = record->fScale * record->fTileSize;
+ desc.fHeight = record->fScale * record->fTileSize;
record->fEntry0 = this->lockKeylessTexture(desc);
@@ -539,39 +568,73 @@ bool GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
return false;
}
}
+ target->saveCurrentDrawState(&record->fSavedState);
+ return true;
+}
+
+void GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
+ const GrIRect& boundRect,
+ int tileX, int tileY,
+ OffscreenRecord* record) {
GrRenderTarget* offRT0 = record->fEntry0->texture()->asRenderTarget();
GrAssert(NULL != offRT0);
- target->saveCurrentDrawState(&record->fSavedState);
-
GrPaint tempPaint;
tempPaint.reset();
SetPaint(tempPaint, target);
target->setRenderTarget(offRT0);
GrMatrix transM;
- transM.setTranslate(-boundRect.fLeft, -boundRect.fTop);
+ int left = boundRect.fLeft + tileX * record->fTileSize;
+ int top = boundRect.fTop + tileY * record->fTileSize;
+ transM.setTranslate(-left * GR_Scalar1, -top * GR_Scalar1);
target->postConcatViewMatrix(transM);
GrMatrix scaleM;
- scaleM.setScale(scale * GR_Scalar1, scale * GR_Scalar1);
+ scaleM.setScale(record->fScale * GR_Scalar1, record->fScale * GR_Scalar1);
target->postConcatViewMatrix(scaleM);
// clip gets applied in second pass
target->disableState(GrDrawTarget::kClip_StateBit);
- GrIRect clear = SkIRect::MakeWH(scale * boundW, scale * boundH);
+ int w = (tileX == record->fTileCountX-1) ? boundRect.fRight - left :
+ record->fTileSize;
+ int h = (tileY == record->fTileCountY-1) ? boundRect.fBottom - top :
+ record->fTileSize;
+ GrIRect clear = SkIRect::MakeWH(record->fScale * w,
+ record->fScale * h);
+#if 0
+ // visualize tile boundaries by setting edges of offscreen to white
+ // and interior to tranparent. black.
+ target->clear(&clear, 0xffffffff);
+
+ static const int gOffset = 2;
+ GrIRect clear2 = SkIRect::MakeLTRB(gOffset, gOffset,
+ record->fScale * w - gOffset,
+ record->fScale * h - gOffset);
+ target->clear(&clear2, 0x0);
+#else
target->clear(&clear, 0x0);
-
- return true;
+#endif
}
-void GrContext::offscreenAAPass2(GrDrawTarget* target,
+void GrContext::doOffscreenAAPass2(GrDrawTarget* target,
const GrPaint& paint,
const GrIRect& boundRect,
+ int tileX, int tileY,
OffscreenRecord* record) {
GrAssert(NULL != record->fEntry0);
+
+ GrIRect tileRect;
+ tileRect.fLeft = boundRect.fLeft + tileX * record->fTileSize;
+ tileRect.fTop = boundRect.fTop + tileY * record->fTileSize,
+ tileRect.fRight = (tileX == record->fTileCountX-1) ?
+ boundRect.fRight :
+ tileRect.fLeft + record->fTileSize;
+ tileRect.fBottom = (tileY == record->fTileCountY-1) ?
+ boundRect.fBottom :
+ tileRect.fTop + record->fTileSize;
GrSamplerState::Filter filter;
if (OffscreenRecord::k4x4SinglePass_Downsample == record->fDownsample) {
@@ -604,14 +667,14 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
scale * GR_Scalar1 / src->height());
sampler.setMatrix(sampleM);
target->setSamplerState(kOffscreenStage, sampler);
- GrRect rect = SkRect::MakeWH(scale * boundRect.width(),
- scale * boundRect.height());
+ GrRect rect = SkRect::MakeWH(scale * tileRect.width(),
+ scale * tileRect.height());
target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage);
src = record->fEntry1->texture();
} else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) {
scale = 1;
- GrIRect rect = SkIRect::MakeWH(boundRect.width(), boundRect.height());
+ GrIRect rect = SkIRect::MakeWH(tileRect.width(), tileRect.height());
src->asRenderTarget()->overrideResolveRect(rect);
} else {
GrAssert(OffscreenRecord::k4x4SinglePass_Downsample ==
@@ -619,7 +682,10 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
scale = 4;
}
- // setup for draw back to main RT
+ // setup for draw back to main RT, we use the original
+ // draw state setup by the caller plus an additional coverage
+ // stage to handle the AA resolve. Also, we use an identity
+ // view matrix and so pre-concat sampler matrices with view inv.
int stageMask = paint.getActiveStageMask();
target->restoreDrawState(record->fSavedState);
@@ -630,21 +696,27 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
target->preConcatSamplerMatrices(stageMask, invVM);
}
}
+ // This is important when tiling, otherwise second tile's
+ // pass 1 view matrix will be incorrect.
+ GrDrawTarget::AutoViewMatrixRestore avmr(target);
+
target->setViewMatrix(GrMatrix::I());
target->setTexture(kOffscreenStage, src);
sampleM.setScale(scale * GR_Scalar1 / src->width(),
scale * GR_Scalar1 / src->height());
sampler.setMatrix(sampleM);
- sampleM.setTranslate(-boundRect.fLeft, -boundRect.fTop);
+ sampleM.setTranslate(-tileRect.fLeft, -tileRect.fTop);
sampler.preConcatMatrix(sampleM);
target->setSamplerState(kOffscreenStage, sampler);
GrRect dstRect;
int stages = (1 << kOffscreenStage) | stageMask;
- dstRect.set(boundRect);
+ dstRect.set(tileRect);
target->drawSimpleRect(dstRect, NULL, stages);
+}
+void GrContext::cleanupOffscreenAA(GrDrawTarget* target, OffscreenRecord* record) {
this->unlockTexture(record->fEntry0);
record->fEntry0 = NULL;
if (NULL != record->fEntry1) {
@@ -1108,10 +1180,6 @@ void GrContext::drawVertices(const GrPaint& paint,
}
int vertexSize = GrDrawTarget::VertexSize(layout);
- bool doAA = false;
- OffscreenRecord record;
- GrIRect bounds;
-
if (sizeof(GrPoint) != vertexSize) {
if (!geo.set(target, layout, vertexCount, 0)) {
GrPrintf("Failed to get space for vertices!");
@@ -1136,36 +1204,20 @@ void GrContext::drawVertices(const GrPaint& paint,
curVertex = (void*)((intptr_t)curVertex + vertexSize);
}
} else {
- // we don't do offscreen AA when we have per-vertex tex coords or colors
- if (this->doOffscreenAA(target, paint, GrIsPrimTypeLines(primitiveType))) {
- GrRect b;
- b.setBounds(positions, vertexCount);
- target->getViewMatrix().mapRect(&b);
- b.roundOut(&bounds);
-
- if (this->setupOffscreenAAPass1(target, false, bounds, &record)) {
- doAA = true;
- }
- }
target->setVertexSourceToArray(layout, positions, vertexCount);
}
- if (NULL != indices) {
- target->setIndexSourceToArray(indices, indexCount);
- }
+ // we don't currently apply offscreen AA to this path. Need improved
+ // management of GrDrawTarget's geometry to avoid copying points per-tile.
if (NULL != indices) {
+ target->setIndexSourceToArray(indices, indexCount);
target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
} else {
target->drawNonIndexed(primitiveType, 0, vertexCount);
}
-
- if (doAA) {
- this->offscreenAAPass2(target, paint, bounds, &record);
- }
}
-
///////////////////////////////////////////////////////////////////////////////
void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
@@ -1178,7 +1230,6 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
!pr->supportsAA(target, path, fill) &&
this->doOffscreenAA(target, paint, kHairLine_PathFill == fill)) {
- OffscreenRecord record;
bool needsStencil = pr->requiresStencilPass(target, path, fill);
// compute bounds as intersection of rt size, clip, and path
@@ -1193,34 +1244,31 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
}
GrRect pathBounds = path.getBounds();
- GrIRect pathIBounds;
if (!pathBounds.isEmpty()) {
if (NULL != translate) {
pathBounds.offset(*translate);
}
target->getViewMatrix().mapRect(&pathBounds, pathBounds);
+ GrIRect pathIBounds;
pathBounds.roundOut(&pathIBounds);
if (!bound.intersect(pathIBounds)) {
return;
}
}
-
- // for now, abort antialiasing if our bounds are too big, so we don't
- // hit the FBO size limit
- if (pathIBounds.width() > GR_MAX_OFFSCREEN_AA_DIM ||
- pathIBounds.height() > GR_MAX_OFFSCREEN_AA_DIM) {
- goto NO_AA;
- }
-
- if (this->setupOffscreenAAPass1(target, needsStencil, bound, &record)) {
- pr->drawPath(target, 0, path, fill, translate);
- this->offscreenAAPass2(target, paint, bound, &record);
+ OffscreenRecord record;
+ if (this->prepareForOffscreenAA(target, needsStencil, bound, &record)) {
+ for (int tx = 0; tx < record.fTileCountX; ++tx) {
+ for (int ty = 0; ty < record.fTileCountY; ++ty) {
+ this->setupOffscreenAAPass1(target, bound, tx, ty, &record);
+ pr->drawPath(target, 0, path, fill, translate);
+ this->doOffscreenAAPass2(target, paint, bound, tx, ty, &record);
+ }
+ }
+ this->cleanupOffscreenAA(target, &record);
return;
}
}
-// we can fall out of the AA section for some reasons, and land here
-NO_AA:
GrDrawTarget::StageBitfield enabledStages = paint.getActiveStageMask();
pr->drawPath(target, enabledStages, path, fill, translate);
@@ -1467,6 +1515,12 @@ GrContext::GrContext(GrGpu* gpu) :
fAAFillRectIndexBuffer = NULL;
fAAStrokeRectIndexBuffer = NULL;
+
+ int gpuMaxOffscreen = fGpu->maxRenderTargetSize();
+ if (!PREFER_MSAA_OFFSCREEN_AA || !fGpu->supportsFullsceneAA()) {
+ gpuMaxOffscreen /= OFFSCREEN_SSAA_SCALE;
+ }
+ fMaxOffscreenAASize = GrMin(GR_MAX_OFFSCREEN_AA_SIZE, gpuMaxOffscreen);
this->setupDrawBuffer();
}
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index ff2d406e3d..70686d7e68 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -439,24 +439,22 @@ GrGpuGL::GrGpuGL() {
}
}
- GR_GL_GetIntegerv(GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureDimension);
+ GR_GL_GetIntegerv(GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
+ GR_GL_GetIntegerv(GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
+ // Our render targets are always created with textures as the color
+ // attachment, hence this min:
+ fMaxRenderTargetSize = GrMin(fMaxTextureSize, fMaxRenderTargetSize);
/* The iPhone 4 has a restriction that for an FBO with texture color
attachment with height <= 8 then the width must be <= height. Here
we look for such a limitation.
*/
- fMinRenderTargetHeight = GR_INVAL_GLINT;
- GrGLint maxRenderSize;
- GR_GL_GetIntegerv(GR_GL_MAX_RENDERBUFFER_SIZE, &maxRenderSize);
- // fbo_test creates FBOs with texture bound to the color attachment
- maxRenderSize = GrMin(maxRenderSize, fMaxTextureDimension);
-
if (gPrintStartupSpew) {
GrPrintf("Small height FBO texture experiments\n");
}
-
+ fMinRenderTargetHeight = GR_INVAL_GLINT;
for (GrGLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? ++i : i *= 2) {
- GrGLuint w = maxRenderSize;
+ GrGLuint w = fMaxRenderTargetSize;
GrGLuint h = i;
if (fbo_test(w, h)) {
if (gPrintStartupSpew) {
@@ -475,10 +473,10 @@ GrGpuGL::GrGpuGL() {
if (gPrintStartupSpew) {
GrPrintf("Small width FBO texture experiments\n");
}
- fMinRenderTargetWidth = GR_MAX_GLUINT;
+ fMinRenderTargetWidth = GR_INVAL_GLINT;
for (GrGLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? i *= 2 : ++i) {
GrGLuint w = i;
- GrGLuint h = maxRenderSize;
+ GrGLuint h = fMaxRenderTargetSize;
if (fbo_test(w, h)) {
if (gPrintStartupSpew) {
GrPrintf("\t[%d, %d]: PASSED\n", w, h);
@@ -792,9 +790,17 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
glDesc.fAllocWidth);
glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight,
glDesc.fAllocHeight);
+ if ((int)glDesc.fAllocWidth > fMaxRenderTargetSize ||
+ (int)glDesc.fAllocHeight > fMaxRenderTargetSize) {
+ return return_null_texture();
+ }
} else if (!this->npotTextureSupport()) {
glDesc.fAllocWidth = GrNextPow2(desc.fWidth);
glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
+ if ((int)glDesc.fAllocWidth > fMaxTextureSize ||
+ (int)glDesc.fAllocHeight > fMaxTextureSize) {
+ return return_null_texture();
+ }
}
GR_GL(BindTexture(GR_GL_TEXTURE_2D, glDesc.fTextureID));