cleanup GrGLTexture / GrGLRenderTarget cons. Make GrRenderTarget aware of its msaa sample count.

Review URL: http://codereview.appspot.com/4833045/



git-svn-id: http://skia.googlecode.com/svn/trunk@1996 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2011-07-29 20:29:05 +00:00
Родитель aa5b6730f2
Коммит 5bfc21761e
10 изменённых файлов: 295 добавлений и 205 удалений

Просмотреть файл

@ -77,7 +77,12 @@ public:
/** /**
* @return true if the render target is multisampled, false otherwise * @return true if the render target is multisampled, false otherwise
*/ */
bool isMultisampled() { return fIsMultisampled; } bool isMultisampled() const { return 0 != fSampleCnt; }
/**
* @return the number of samples-per-pixel or zero if non-MSAA.
*/
int numSamples() const { return fSampleCnt; }
/** /**
* Call to indicate the multisample contents were modified such that the * Call to indicate the multisample contents were modified such that the
@ -147,14 +152,14 @@ protected:
int height, int height,
GrPixelConfig config, GrPixelConfig config,
int stencilBits, int stencilBits,
bool isMultisampled) int sampleCnt)
: INHERITED(gpu) : INHERITED(gpu)
, fTexture(texture) , fTexture(texture)
, fWidth(width) , fWidth(width)
, fHeight(height) , fHeight(height)
, fConfig(config) , fConfig(config)
, fStencilBits(stencilBits) , fStencilBits(stencilBits)
, fIsMultisampled(isMultisampled) , fSampleCnt(sampleCnt)
{ {
fResolveRect.setLargestInverted(); fResolveRect.setLargestInverted();
} }
@ -176,7 +181,7 @@ private:
int fHeight; int fHeight;
GrPixelConfig fConfig; GrPixelConfig fConfig;
int fStencilBits; int fStencilBits;
bool fIsMultisampled; int fSampleCnt;
GrIRect fResolveRect; GrIRect fResolveRect;
// GrGpu keeps a cached clip in the render target to avoid redundantly // GrGpu keeps a cached clip in the render target to avoid redundantly

Просмотреть файл

@ -506,10 +506,14 @@ enum GrPlatformSurfaceType {
enum GrPlatformRenderTargetFlags { enum GrPlatformRenderTargetFlags {
kNone_GrPlatformRenderTargetFlagBit = 0x0, kNone_GrPlatformRenderTargetFlagBit = 0x0,
/** /**
* Specifies that the object being created is multisampled. * Specifies that the object being created is multisampled.
* WILL BE REMOVED ONCE WEBKIT STOPS USING THIS. INSTEAD
* SPECIFY # OF SAMPLES IN GrPlatformSurfaceDesc::fSampleCnt
*/ */
kIsMultisampled_GrPlatformRenderTargetFlagBit = 0x1, kIsMultisampled_GrPlatformRenderTargetFlagBit = 0x1,
/** /**
* Gives permission to Gr to perform the downsample-resolve of a * Gives permission to Gr to perform the downsample-resolve of a
* multisampled render target. If this is not set then read pixel * multisampled render target. If this is not set then read pixel
@ -545,6 +549,13 @@ struct GrPlatformSurfaceDesc {
* set in fFlags. * set in fFlags.
*/ */
int fStencilBits; int fStencilBits;
/**
* Number of samples per-pixel. Only relevant if kIsRenderTarget is set in
* fFlags.
*/
int fSampleCnt;
/** /**
* Texture object in 3D API. Only relevant if fSurfaceType is kTexture or * Texture object in 3D API. Only relevant if fSurfaceType is kTexture or
* kTextureRenderTarget. * kTextureRenderTarget.
@ -600,11 +611,12 @@ struct GrPlatformSurfaceDesc {
* *
* GrPlatformSurfaceDesc renderTargetTextureDesc; * GrPlatformSurfaceDesc renderTargetTextureDesc;
* renderTargetTextureDesc.fSurfaceType = kTextureRenderTarget_GrPlatformSurfaceType; * renderTargetTextureDesc.fSurfaceType = kTextureRenderTarget_GrPlatformSurfaceType;
* renderTargetTextureDesc.fRenderTargetFlags = (kIsMultisampled_GrPlatformRenderTargetFlagBit | kGrCanResolve_GrPlatformRenderTargetFlagBit); * renderTargetTextureDesc.fRenderTargetFlags = kGrCanResolve_GrPlatformRenderTargetFlagBit;
* renderTargetTextureDesc.fWidth = W; * renderTargetTextureDesc.fWidth = W;
* renderTargetTextureDesc.fHeight = H; * renderTargetTextureDesc.fHeight = H;
* renderTargetTextureDesc.fConfig = kRGBA_8888_GrPixelConfig * renderTargetTextureDesc.fConfig = kRGBA_8888_GrPixelConfig
* renderTargetTextureDesc.fStencilBits = 8; * renderTargetTextureDesc.fStencilBits = 8;
* renderTargetTextureDesc.fSampleCnt = S;
* renderTargetTextureDesc.fPlatformTexture = textureID; * renderTargetTextureDesc.fPlatformTexture = textureID;
* renderTargetTextureDesc.fPlatformRenderTarget = drawFBOID; * renderTargetTextureDesc.fPlatformRenderTarget = drawFBOID;
* renderTargetTextureDesc.fPlatformResolveDestination = readFBOID; * renderTargetTextureDesc.fPlatformResolveDestination = readFBOID;

Просмотреть файл

@ -465,6 +465,7 @@ GrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc)
0 != desc.fRenderTargetFlags) { 0 != desc.fRenderTargetFlags) {
return NULL; return NULL;
} }
#if GR_USE_PLATFORM_CREATE_SAMPLE_COUNT
if (!(kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) && if (!(kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) &&
(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
return NULL; return NULL;
@ -474,6 +475,17 @@ GrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc)
!(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { !(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
return NULL; return NULL;
} }
#else
if (desc.fSampleCnt &&
(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
return NULL;
}
if (kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType &&
desc.fSampleCnt &&
!(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
return NULL;
}
#endif
return fGpu->createPlatformSurface(desc); return fGpu->createPlatformSurface(desc);
} }

Просмотреть файл

@ -13,27 +13,44 @@
#define GPUGL static_cast<GrGpuGL*>(getGpu()) #define GPUGL static_cast<GrGpuGL*>(getGpu())
GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu, void GrGLRenderTarget::init(const Desc& desc,
const GLRenderTargetIDs& ids, const GrGLIRect& viewport,
GrGLTexID* texID, GrGLTexID* texID) {
GrPixelConfig config, fRTFBOID = desc.fRTFBOID;
GrGLuint stencilBits, fTexFBOID = desc.fTexFBOID;
bool isMultisampled, fMSColorRenderbufferID = desc.fMSColorRenderbufferID;
const GrGLIRect& viewport, fStencilRenderbufferID = desc.fStencilRenderbufferID;
GrGLTexture* texture)
: INHERITED(gpu, texture, viewport.fWidth,
viewport.fHeight, config,
stencilBits, isMultisampled) {
fRTFBOID = ids.fRTFBOID;
fTexFBOID = ids.fTexFBOID;
fStencilRenderbufferID = ids.fStencilRenderbufferID;
fMSColorRenderbufferID = ids.fMSColorRenderbufferID;
fViewport = viewport; fViewport = viewport;
fOwnIDs = ids.fOwnIDs; fOwnIDs = desc.fOwnIDs;
fTexIDObj = texID; fTexIDObj = texID;
GrSafeRef(fTexIDObj); GrSafeRef(fTexIDObj);
} }
GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
const Desc& desc,
const GrGLIRect& viewport,
GrGLTexID* texID,
GrGLTexture* texture)
: INHERITED(gpu, texture, viewport.fWidth,
viewport.fHeight, desc.fConfig,
desc.fStencilBits, desc.fSampleCnt) {
GrAssert(NULL != texID);
GrAssert(NULL != texture);
// FBO 0 can't also be a texture, right?
GrAssert(0 != desc.fRTFBOID);
GrAssert(0 != desc.fTexFBOID);
this->init(desc, viewport, texID);
}
GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
const Desc& desc,
const GrGLIRect& viewport)
: INHERITED(gpu, NULL, viewport.fWidth,
viewport.fHeight, desc.fConfig,
desc.fStencilBits, desc.fSampleCnt) {
this->init(desc, viewport, NULL);
}
void GrGLRenderTarget::onRelease() { void GrGLRenderTarget::onRelease() {
GPUGL->notifyRenderTargetDelete(this); GPUGL->notifyRenderTargetDelete(this);
if (fOwnIDs) { if (fOwnIDs) {

Просмотреть файл

@ -25,23 +25,28 @@ public:
// Gr doesn't know how to resolve it. // Gr doesn't know how to resolve it.
enum { kUnresolvableFBOID = 0 }; enum { kUnresolvableFBOID = 0 };
struct GLRenderTargetIDs { struct Desc {
GrGLuint fRTFBOID; GrGLuint fRTFBOID;
GrGLuint fTexFBOID; GrGLuint fTexFBOID;
GrGLuint fStencilRenderbufferID; GrGLuint fStencilRenderbufferID;
GrGLuint fMSColorRenderbufferID; GrGLuint fMSColorRenderbufferID;
bool fOwnIDs; bool fOwnIDs;
void reset() { memset(this, 0, sizeof(GLRenderTargetIDs)); } GrPixelConfig fConfig;
int fStencilBits;
int fSampleCnt;
}; };
GrGLRenderTarget(GrGpuGL* gpu, // creates a GrGLRenderTarget associated with a texture
const GLRenderTargetIDs& ids, GrGLRenderTarget(GrGpuGL* gpu,
GrGLTexID* texID, const Desc& desc,
GrPixelConfig config, const GrGLIRect& viewport,
GrGLuint stencilBits, GrGLTexID* texID,
bool isMultisampled, GrGLTexture* texture);
const GrGLIRect& fViewport,
GrGLTexture* texture); // creates an independent GrGLRenderTarget
GrGLRenderTarget(GrGpuGL* gpu,
const Desc& desc,
const GrGLIRect& viewport);
virtual ~GrGLRenderTarget() { this->release(); } virtual ~GrGLRenderTarget() { this->release(); }
@ -97,6 +102,8 @@ private:
// non-NULL if this RT was created by Gr with an associated GrGLTexture. // non-NULL if this RT was created by Gr with an associated GrGLTexture.
GrGLTexID* fTexIDObj; GrGLTexID* fTexIDObj;
void init(const Desc& desc, const GrGLIRect& viewport, GrGLTexID* texID);
typedef GrRenderTarget INHERITED; typedef GrRenderTarget INHERITED;
}; };

Просмотреть файл

@ -33,14 +33,12 @@ const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
} }
}; };
GrGLTexture::GrGLTexture(GrGpuGL* gpu, void GrGLTexture::init(GrGpuGL* gpu,
const GLTextureDesc& textureDesc, const Desc& textureDesc,
const GLRenderTargetIDs& rtIDs, const GrGLRenderTarget::Desc* rtDesc,
const TexParams& initialTexParams) const TexParams& initialTexParams) {
: INHERITED(gpu,
textureDesc.fContentWidth, GrAssert(0 != textureDesc.fTextureID);
textureDesc.fContentHeight,
textureDesc.fFormat) {
fTexParams = initialTexParams; fTexParams = initialTexParams;
fTexIDObj = new GrGLTexID(textureDesc.fTextureID, fTexIDObj = new GrGLTexID(textureDesc.fTextureID,
@ -56,9 +54,7 @@ GrGLTexture::GrGLTexture(GrGpuGL* gpu,
fScaleY = GrIntToScalar(textureDesc.fContentHeight) / fScaleY = GrIntToScalar(textureDesc.fContentHeight) /
textureDesc.fAllocHeight; textureDesc.fAllocHeight;
GrAssert(0 != textureDesc.fTextureID); if (NULL != rtDesc) {
if (rtIDs.fTexFBOID) {
// we render to the top left // we render to the top left
GrGLIRect vp; GrGLIRect vp;
vp.fLeft = 0; vp.fLeft = 0;
@ -66,14 +62,31 @@ GrGLTexture::GrGLTexture(GrGpuGL* gpu,
vp.fHeight = textureDesc.fContentHeight; vp.fHeight = textureDesc.fContentHeight;
vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight; vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj, fRenderTarget = new GrGLRenderTarget(gpu, *rtDesc, vp, fTexIDObj, this);
textureDesc.fFormat,
textureDesc.fStencilBits,
rtIDs.fRTFBOID != rtIDs.fTexFBOID,
vp, this);
} }
} }
GrGLTexture::GrGLTexture(GrGpuGL* gpu,
const Desc& textureDesc,
const TexParams& initialTexParams)
: INHERITED(gpu,
textureDesc.fContentWidth,
textureDesc.fContentHeight,
textureDesc.fFormat) {
this->init(gpu, textureDesc, NULL, initialTexParams);
}
GrGLTexture::GrGLTexture(GrGpuGL* gpu,
const Desc& textureDesc,
const GrGLRenderTarget::Desc& rtDesc,
const TexParams& initialTexParams)
: INHERITED(gpu,
textureDesc.fContentWidth,
textureDesc.fContentHeight,
textureDesc.fFormat) {
this->init(gpu, textureDesc, &rtDesc, initialTexParams);
}
void GrGLTexture::onRelease() { void GrGLTexture::onRelease() {
INHERITED::onRelease(); INHERITED::onRelease();
GPUGL->notifyTextureDelete(this); GPUGL->notifyTextureDelete(this);

Просмотреть файл

@ -54,7 +54,7 @@ public:
void invalidate() { memset(this, 0xff, sizeof(TexParams)); } void invalidate() { memset(this, 0xff, sizeof(TexParams)); }
}; };
struct GLTextureDesc { struct Desc {
int fContentWidth; int fContentWidth;
int fContentHeight; int fContentHeight;
int fAllocWidth; int fAllocWidth;
@ -65,17 +65,21 @@ public:
GrGLenum fUploadFormat; GrGLenum fUploadFormat;
GrGLenum fUploadByteCount; GrGLenum fUploadByteCount;
GrGLenum fUploadType; GrGLenum fUploadType;
GrGLuint fStencilBits;
Orientation fOrientation; Orientation fOrientation;
}; };
typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs; // creates a texture that is also an RT
GrGLTexture(GrGpuGL* gpu, GrGLTexture(GrGpuGL* gpu,
const GLTextureDesc& textureDesc, const Desc& textureDesc,
const GLRenderTargetIDs& rtIDs, const GrGLRenderTarget::Desc& rtDesc,
const TexParams& initialTexParams); const TexParams& initialTexParams);
// creates a non-RT texture
GrGLTexture(GrGpuGL* gpu,
const Desc& textureDesc,
const TexParams& initialTexParams);
virtual ~GrGLTexture() { this->release(); } virtual ~GrGLTexture() { this->release(); }
// overrides of GrTexture // overrides of GrTexture
@ -150,6 +154,11 @@ private:
GrScalar fScaleY; GrScalar fScaleY;
Orientation fOrientation; Orientation fOrientation;
void init(GrGpuGL* gpu,
const Desc& textureDesc,
const GrGLRenderTarget::Desc* rtDesc,
const TexParams& initialTexParams);
typedef GrTexture INHERITED; typedef GrTexture INHERITED;
}; };

Просмотреть файл

@ -597,31 +597,45 @@ GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc)
bool isRenderTarget = kRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType || bool isRenderTarget = kRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType ||
kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType; kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType;
GrGLRenderTarget::GLRenderTargetIDs rtIDs; GrGLRenderTarget::Desc rtDesc;
if (isRenderTarget) { if (isRenderTarget) {
rtIDs.fRTFBOID = desc.fPlatformRenderTarget; rtDesc.fRTFBOID = desc.fPlatformRenderTarget;
#if GR_USE_PLATFORM_CREATE_SAMPLE_COUNT
if (desc.fSampleCnt) {
#else
if (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) { if (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) {
#endif
if (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) { if (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) {
rtIDs.fTexFBOID = desc.fPlatformResolveDestination; rtDesc.fTexFBOID = desc.fPlatformResolveDestination;
} else { } else {
GrAssert(!isTexture); // this should have been filtered by GrContext GrAssert(!isTexture); // this should have been filtered by GrContext
rtIDs.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; rtDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
} }
} else { } else {
rtIDs.fTexFBOID = desc.fPlatformRenderTarget; rtDesc.fTexFBOID = desc.fPlatformRenderTarget;
} }
// we don't know what the RB ids are without glGets and we don't care // we don't know what the RB ids are without glGets and we don't care
// since we aren't responsible for deleting them. // since we aren't responsible for deleting them.
rtIDs.fStencilRenderbufferID = 0; rtDesc.fStencilRenderbufferID = 0;
rtIDs.fMSColorRenderbufferID = 0; rtDesc.fMSColorRenderbufferID = 0;
#if GR_USE_PLATFORM_CREATE_SAMPLE_COUNT
rtIDs.fOwnIDs = false; rtDesc.fSampleCnt = desc.fSampleCnt;
} else { #else
rtIDs.reset(); if (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) {
// just guess, this code path is only compiled in WK and we aren't
// using MSAA anyway. This will be stripped out soon when WK sets
// the fSampleCnt in GrPlatformSurfaceDesc.
rtDesc.fSampleCnt = 4;
} else {
rtDesc.fSampleCnt = 0;
}
#endif
rtDesc.fStencilBits = desc.fStencilBits;
rtDesc.fOwnIDs = false;
} }
if (isTexture) { if (isTexture) {
GrGLTexture::GLTextureDesc texDesc; GrGLTexture::Desc texDesc;
GrGLenum dontCare; GrGLenum dontCare;
if (!canBeTexture(desc.fConfig, &dontCare, if (!canBeTexture(desc.fConfig, &dontCare,
&texDesc.fUploadFormat, &texDesc.fUploadFormat,
@ -636,14 +650,16 @@ GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc)
texDesc.fFormat = desc.fConfig; texDesc.fFormat = desc.fConfig;
texDesc.fOrientation = GrGLTexture::kBottomUp_Orientation; texDesc.fOrientation = GrGLTexture::kBottomUp_Orientation;
texDesc.fStencilBits = desc.fStencilBits;
texDesc.fTextureID = desc.fPlatformTexture; texDesc.fTextureID = desc.fPlatformTexture;
texDesc.fUploadByteCount = GrBytesPerPixel(desc.fConfig); texDesc.fUploadByteCount = GrBytesPerPixel(desc.fConfig);
texDesc.fOwnsID = false; texDesc.fOwnsID = false;
params.invalidate(); // rather than do glGets. params.invalidate(); // rather than do glGets.
if (isRenderTarget) {
return new GrGLTexture(this, texDesc, rtIDs, params); return new GrGLTexture(this, texDesc, rtDesc, params);
} else {
return new GrGLTexture(this, texDesc, params);
}
} else { } else {
GrGLIRect viewport; GrGLIRect viewport;
viewport.fLeft = 0; viewport.fLeft = 0;
@ -651,11 +667,7 @@ GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc)
viewport.fWidth = desc.fWidth; viewport.fWidth = desc.fWidth;
viewport.fHeight = desc.fHeight; viewport.fHeight = desc.fHeight;
bool isMSAA = kIsMultisampled_GrPlatformRenderTargetFlagBit & return new GrGLRenderTarget(this, rtDesc, viewport);
desc.fRenderTargetFlags;
return new GrGLRenderTarget(this, rtIDs, NULL, desc.fConfig,
desc.fStencilBits, isMSAA, viewport, NULL);
} }
} }
@ -799,37 +811,34 @@ int get_fbo_stencil_bits(bool arbFBOExtension) {
GrRenderTarget* GrGpuGL::onCreateRenderTargetFrom3DApiState() { GrRenderTarget* GrGpuGL::onCreateRenderTargetFrom3DApiState() {
GrGLRenderTarget::GLRenderTargetIDs rtIDs; GrGLRenderTarget::Desc rtDesc;
GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, (GrGLint*)&rtIDs.fRTFBOID); GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, (GrGLint*)&rtDesc.fRTFBOID);
rtIDs.fTexFBOID = rtIDs.fRTFBOID; rtDesc.fTexFBOID = rtDesc.fRTFBOID;
rtIDs.fMSColorRenderbufferID = 0; rtDesc.fMSColorRenderbufferID = 0;
rtIDs.fStencilRenderbufferID = 0; rtDesc.fStencilRenderbufferID = 0;
bool arbFBO = (GR_GL_SUPPORT_DESKTOP && (fGLVersion > 3.0 || bool arbFBO = (GR_GL_SUPPORT_DESKTOP && (fGLVersion > 3.0 ||
this->hasExtension("GL_ARB_framebuffer_object"))); this->hasExtension("GL_ARB_framebuffer_object")));
GrGLIRect viewport; GrGLIRect viewport;
viewport.setFromGLViewport(); viewport.setFromGLViewport();
int stencilBits = get_fbo_stencil_bits(arbFBO); rtDesc.fStencilBits = get_fbo_stencil_bits(arbFBO);
GrPixelConfig config; GR_GL_GetIntegerv(GR_GL_SAMPLES, &rtDesc.fSampleCnt);
GrGLint samples;
GR_GL_GetIntegerv(GR_GL_SAMPLES, &samples);
GrGLenum fmat = get_fbo_color_format(); GrGLenum fmat = get_fbo_color_format();
if (kUnknownGLFormat == fmat) { if (kUnknownGLFormat == fmat) {
config = get_implied_color_config(arbFBO); rtDesc.fConfig = get_implied_color_config(arbFBO);
} else { } else {
config = internal_color_format_to_config(fmat); rtDesc.fConfig = internal_color_format_to_config(fmat);
} }
// may have to bind a texture to gets its format // may have to bind a texture to gets its format
this->setSpareTextureUnit(); this->setSpareTextureUnit();
rtIDs.fOwnIDs = false; rtDesc.fOwnIDs = false;
return new GrGLRenderTarget(this, rtIDs, NULL, config, stencilBits, return new GrGLRenderTarget(this, rtDesc, viewport);
(samples > 0), viewport, NULL);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -916,29 +925,28 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GR_GL_CLAMP_TO_EDGE GR_GL_CLAMP_TO_EDGE
}; };
GrGLTexture::GLTextureDesc glDesc; GrGLTexture::Desc glTexDesc;
GrGLenum internalFormat; GrGLenum internalFormat;
glDesc.fContentWidth = desc.fWidth; glTexDesc.fContentWidth = desc.fWidth;
glDesc.fContentHeight = desc.fHeight; glTexDesc.fContentHeight = desc.fHeight;
glDesc.fAllocWidth = desc.fWidth; glTexDesc.fAllocWidth = desc.fWidth;
glDesc.fAllocHeight = desc.fHeight; glTexDesc.fAllocHeight = desc.fHeight;
glDesc.fStencilBits = 0; glTexDesc.fFormat = desc.fFormat;
glDesc.fFormat = desc.fFormat; glTexDesc.fOwnsID = true;
glDesc.fOwnsID = true;
bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit); bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit);
if (!canBeTexture(desc.fFormat, if (!canBeTexture(desc.fFormat,
&internalFormat, &internalFormat,
&glDesc.fUploadFormat, &glTexDesc.fUploadFormat,
&glDesc.fUploadType)) { &glTexDesc.fUploadType)) {
return return_null_texture(); return return_null_texture();
} }
// We keep GrRenderTargets in GL's normal orientation so that they // We keep GrRenderTargets in GL's normal orientation so that they
// can be drawn to by the outside world without the client having // can be drawn to by the outside world without the client having
// to render upside down. // to render upside down.
glDesc.fOrientation = renderTarget ? GrGLTexture::kBottomUp_Orientation : glTexDesc.fOrientation = renderTarget ? GrGLTexture::kBottomUp_Orientation :
GrGLTexture::kTopDown_Orientation; GrGLTexture::kTopDown_Orientation;
GrAssert(as_size_t(desc.fAALevel) < GR_ARRAY_COUNT(fAASamples)); GrAssert(as_size_t(desc.fAALevel) < GR_ARRAY_COUNT(fAASamples));
@ -947,13 +955,13 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GrPrintf("AA RT requested but not supported on this platform."); GrPrintf("AA RT requested but not supported on this platform.");
} }
glDesc.fUploadByteCount = GrBytesPerPixel(desc.fFormat); glTexDesc.fUploadByteCount = GrBytesPerPixel(desc.fFormat);
// in case we need a temporary, trimmed copy of the src pixels // in case we need a temporary, trimmed copy of the src pixels
SkAutoSMalloc<128 * 128> tempStorage; SkAutoSMalloc<128 * 128> tempStorage;
if (!rowBytes) { if (!rowBytes) {
rowBytes = glDesc.fUploadByteCount * desc.fWidth; rowBytes = glTexDesc.fUploadByteCount * desc.fWidth;
} }
/* /*
* check whether to allocate a temporary buffer for flipping y or * check whether to allocate a temporary buffer for flipping y or
@ -961,14 +969,14 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
* to trim those off here, since GL ES doesn't let us specify * to trim those off here, since GL ES doesn't let us specify
* GL_UNPACK_ROW_LENGTH. * GL_UNPACK_ROW_LENGTH.
*/ */
bool flipY = GrGLTexture::kBottomUp_Orientation == glDesc.fOrientation; bool flipY = GrGLTexture::kBottomUp_Orientation == glTexDesc.fOrientation;
if (GR_GL_SUPPORT_DESKTOP && !flipY) { if (GR_GL_SUPPORT_DESKTOP && !flipY) {
if (srcData && rowBytes != desc.fWidth * glDesc.fUploadByteCount) { if (srcData && rowBytes != desc.fWidth * glTexDesc.fUploadByteCount) {
GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH,
rowBytes / glDesc.fUploadByteCount)); rowBytes / glTexDesc.fUploadByteCount));
} }
} else { } else {
size_t trimRowBytes = desc.fWidth * glDesc.fUploadByteCount; size_t trimRowBytes = desc.fWidth * glTexDesc.fUploadByteCount;
if (srcData && (trimRowBytes < rowBytes || flipY)) { if (srcData && (trimRowBytes < rowBytes || flipY)) {
// copy the data into our new storage, skipping the trailing bytes // copy the data into our new storage, skipping the trailing bytes
size_t trimSize = desc.fHeight * trimRowBytes; size_t trimSize = desc.fHeight * trimRowBytes;
@ -994,33 +1002,33 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
if (renderTarget) { if (renderTarget) {
if (!this->npotRenderTargetSupport()) { if (!this->npotRenderTargetSupport()) {
glDesc.fAllocWidth = GrNextPow2(desc.fWidth); glTexDesc.fAllocWidth = GrNextPow2(desc.fWidth);
glDesc.fAllocHeight = GrNextPow2(desc.fHeight); glTexDesc.fAllocHeight = GrNextPow2(desc.fHeight);
} }
glDesc.fAllocWidth = GrMax(fMinRenderTargetWidth, glTexDesc.fAllocWidth = GrMax(fMinRenderTargetWidth,
glDesc.fAllocWidth); glTexDesc.fAllocWidth);
glDesc.fAllocHeight = GrMax(fMinRenderTargetHeight, glTexDesc.fAllocHeight = GrMax(fMinRenderTargetHeight,
glDesc.fAllocHeight); glTexDesc.fAllocHeight);
if (glDesc.fAllocWidth > fMaxRenderTargetSize || if (glTexDesc.fAllocWidth > fMaxRenderTargetSize ||
glDesc.fAllocHeight > fMaxRenderTargetSize) { glTexDesc.fAllocHeight > fMaxRenderTargetSize) {
return return_null_texture(); return return_null_texture();
} }
} else if (!this->npotTextureSupport()) { } else if (!this->npotTextureSupport()) {
glDesc.fAllocWidth = GrNextPow2(desc.fWidth); glTexDesc.fAllocWidth = GrNextPow2(desc.fWidth);
glDesc.fAllocHeight = GrNextPow2(desc.fHeight); glTexDesc.fAllocHeight = GrNextPow2(desc.fHeight);
if (glDesc.fAllocWidth > fMaxTextureSize || if (glTexDesc.fAllocWidth > fMaxTextureSize ||
glDesc.fAllocHeight > fMaxTextureSize) { glTexDesc.fAllocHeight > fMaxTextureSize) {
return return_null_texture(); return return_null_texture();
} }
} }
GR_GL(GenTextures(1, &glDesc.fTextureID)); GR_GL(GenTextures(1, &glTexDesc.fTextureID));
if (!glDesc.fTextureID) { if (!glTexDesc.fTextureID) {
return return_null_texture(); return return_null_texture();
} }
GR_GL(BindTexture(GR_GL_TEXTURE_2D, glDesc.fTextureID)); GR_GL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
GR_GL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL(TexParameteri(GR_GL_TEXTURE_2D,
GR_GL_TEXTURE_MAG_FILTER, GR_GL_TEXTURE_MAG_FILTER,
DEFAULT_PARAMS.fFilter)); DEFAULT_PARAMS.fFilter));
@ -1034,41 +1042,41 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GR_GL_TEXTURE_WRAP_T, GR_GL_TEXTURE_WRAP_T,
DEFAULT_PARAMS.fWrapT)); DEFAULT_PARAMS.fWrapT));
GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, glDesc.fUploadByteCount)); GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, glTexDesc.fUploadByteCount));
if (kIndex_8_GrPixelConfig == desc.fFormat && if (kIndex_8_GrPixelConfig == desc.fFormat &&
supports8BitPalette()) { supports8BitPalette()) {
// ES only supports CompressedTexImage2D, not CompressedTexSubimage2D // ES only supports CompressedTexImage2D, not CompressedTexSubimage2D
GrAssert(desc.fWidth == glDesc.fAllocWidth); GrAssert(desc.fWidth == glTexDesc.fAllocWidth);
GrAssert(desc.fHeight == glDesc.fAllocHeight); GrAssert(desc.fHeight == glTexDesc.fAllocHeight);
GrGLsizei imageSize = glDesc.fAllocWidth * glDesc.fAllocHeight + GrGLsizei imageSize = glTexDesc.fAllocWidth * glTexDesc.fAllocHeight +
kGrColorTableSize; kGrColorTableSize;
GR_GL(CompressedTexImage2D(GR_GL_TEXTURE_2D, 0, glDesc.fUploadFormat, GR_GL(CompressedTexImage2D(GR_GL_TEXTURE_2D, 0, glTexDesc.fUploadFormat,
glDesc.fAllocWidth, glDesc.fAllocHeight, glTexDesc.fAllocWidth, glTexDesc.fAllocHeight,
0, imageSize, srcData)); 0, imageSize, srcData));
GrGLRestoreResetRowLength(); GrGLRestoreResetRowLength();
} else { } else {
if (NULL != srcData && (glDesc.fAllocWidth != desc.fWidth || if (NULL != srcData && (glTexDesc.fAllocWidth != desc.fWidth ||
glDesc.fAllocHeight != desc.fHeight)) { glTexDesc.fAllocHeight != desc.fHeight)) {
GR_GL(TexImage2D(GR_GL_TEXTURE_2D, 0, internalFormat, GR_GL(TexImage2D(GR_GL_TEXTURE_2D, 0, internalFormat,
glDesc.fAllocWidth, glDesc.fAllocHeight, glTexDesc.fAllocWidth, glTexDesc.fAllocHeight,
0, glDesc.fUploadFormat, glDesc.fUploadType, NULL)); 0, glTexDesc.fUploadFormat, glTexDesc.fUploadType, NULL));
GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, 0, 0, desc.fWidth, GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, 0, 0, desc.fWidth,
desc.fHeight, glDesc.fUploadFormat, desc.fHeight, glTexDesc.fUploadFormat,
glDesc.fUploadType, srcData)); glTexDesc.fUploadType, srcData));
GrGLRestoreResetRowLength(); GrGLRestoreResetRowLength();
int extraW = glDesc.fAllocWidth - desc.fWidth; int extraW = glTexDesc.fAllocWidth - desc.fWidth;
int extraH = glDesc.fAllocHeight - desc.fHeight; int extraH = glTexDesc.fAllocHeight - desc.fHeight;
int maxTexels = extraW * extraH; int maxTexels = extraW * extraH;
maxTexels = GrMax(extraW * desc.fHeight, maxTexels); maxTexels = GrMax(extraW * desc.fHeight, maxTexels);
maxTexels = GrMax(desc.fWidth * extraH, maxTexels); maxTexels = GrMax(desc.fWidth * extraH, maxTexels);
SkAutoSMalloc<128*128> texels(glDesc.fUploadByteCount * maxTexels); SkAutoSMalloc<128*128> texels(glTexDesc.fUploadByteCount * maxTexels);
// rowBytes is actual stride between rows in srcData // rowBytes is actual stride between rows in srcData
// rowDataBytes is the actual amount of non-pad data in a row // rowDataBytes is the actual amount of non-pad data in a row
// and the stride used for uploading extraH rows. // and the stride used for uploading extraH rows.
uint32_t rowDataBytes = desc.fWidth * glDesc.fUploadByteCount; uint32_t rowDataBytes = desc.fWidth * glTexDesc.fUploadByteCount;
if (extraH) { if (extraH) {
uint8_t* lastRowStart = (uint8_t*) srcData + uint8_t* lastRowStart = (uint8_t*) srcData +
(desc.fHeight - 1) * rowBytes; (desc.fHeight - 1) * rowBytes;
@ -1079,51 +1087,54 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
extraRowStart += rowDataBytes; extraRowStart += rowDataBytes;
} }
GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, 0, desc.fHeight, desc.fWidth, GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, 0, desc.fHeight, desc.fWidth,
extraH, glDesc.fUploadFormat, glDesc.fUploadType, extraH, glTexDesc.fUploadFormat, glTexDesc.fUploadType,
texels.get())); texels.get()));
} }
if (extraW) { if (extraW) {
uint8_t* edgeTexel = (uint8_t*)srcData + rowDataBytes - glDesc.fUploadByteCount; uint8_t* edgeTexel = (uint8_t*)srcData + rowDataBytes - glTexDesc.fUploadByteCount;
uint8_t* extraTexel = (uint8_t*)texels.get(); uint8_t* extraTexel = (uint8_t*)texels.get();
for (int j = 0; j < desc.fHeight; ++j) { for (int j = 0; j < desc.fHeight; ++j) {
for (int i = 0; i < extraW; ++i) { for (int i = 0; i < extraW; ++i) {
memcpy(extraTexel, edgeTexel, glDesc.fUploadByteCount); memcpy(extraTexel, edgeTexel, glTexDesc.fUploadByteCount);
extraTexel += glDesc.fUploadByteCount; extraTexel += glTexDesc.fUploadByteCount;
} }
edgeTexel += rowBytes; edgeTexel += rowBytes;
} }
GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, desc.fWidth, 0, extraW, GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, desc.fWidth, 0, extraW,
desc.fHeight, glDesc.fUploadFormat, desc.fHeight, glTexDesc.fUploadFormat,
glDesc.fUploadType, texels.get())); glTexDesc.fUploadType, texels.get()));
} }
if (extraW && extraH) { if (extraW && extraH) {
uint8_t* cornerTexel = (uint8_t*)srcData + desc.fHeight * rowBytes uint8_t* cornerTexel = (uint8_t*)srcData + desc.fHeight * rowBytes
- glDesc.fUploadByteCount; - glTexDesc.fUploadByteCount;
uint8_t* extraTexel = (uint8_t*)texels.get(); uint8_t* extraTexel = (uint8_t*)texels.get();
for (int i = 0; i < extraW*extraH; ++i) { for (int i = 0; i < extraW*extraH; ++i) {
memcpy(extraTexel, cornerTexel, glDesc.fUploadByteCount); memcpy(extraTexel, cornerTexel, glTexDesc.fUploadByteCount);
extraTexel += glDesc.fUploadByteCount; extraTexel += glTexDesc.fUploadByteCount;
} }
GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, desc.fWidth, desc.fHeight, GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, desc.fWidth, desc.fHeight,
extraW, extraH, glDesc.fUploadFormat, extraW, extraH, glTexDesc.fUploadFormat,
glDesc.fUploadType, texels.get())); glTexDesc.fUploadType, texels.get()));
} }
} else { } else {
GR_GL(TexImage2D(GR_GL_TEXTURE_2D, 0, internalFormat, glDesc.fAllocWidth, GR_GL(TexImage2D(GR_GL_TEXTURE_2D, 0, internalFormat, glTexDesc.fAllocWidth,
glDesc.fAllocHeight, 0, glDesc.fUploadFormat, glTexDesc.fAllocHeight, 0, glTexDesc.fUploadFormat,
glDesc.fUploadType, srcData)); glTexDesc.fUploadType, srcData));
GrGLRestoreResetRowLength(); GrGLRestoreResetRowLength();
} }
} }
GrGLRenderTarget::GLRenderTargetIDs rtIDs; GrGLRenderTarget::Desc glRTDesc;
rtIDs.fStencilRenderbufferID = 0; glRTDesc.fStencilRenderbufferID = 0;
rtIDs.fMSColorRenderbufferID = 0; glRTDesc.fMSColorRenderbufferID = 0;
rtIDs.fRTFBOID = 0; glRTDesc.fRTFBOID = 0;
rtIDs.fTexFBOID = 0; glRTDesc.fTexFBOID = 0;
rtIDs.fOwnIDs = true; glRTDesc.fOwnIDs = true;
glRTDesc.fConfig = glTexDesc.fFormat;
glRTDesc.fSampleCnt = samples;
GrGLenum msColorRenderbufferFormat = -1; GrGLenum msColorRenderbufferFormat = -1;
if (renderTarget) { if (renderTarget) {
@ -1134,29 +1145,29 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GrGLenum status; GrGLenum status;
GrGLint err; GrGLint err;
GR_GL(GenFramebuffers(1, &rtIDs.fTexFBOID)); GR_GL(GenFramebuffers(1, &glRTDesc.fTexFBOID));
GrAssert(rtIDs.fTexFBOID); GrAssert(glRTDesc.fTexFBOID);
// If we are using multisampling and we will create two FBOS We render // If we are using multisampling and we will create two FBOS We render
// to one and then resolve to the texture bound to the other. // to one and then resolve to the texture bound to the other.
if (samples > 1 && kNone_MSFBO != fMSFBOType) { if (samples > 1 && kNone_MSFBO != fMSFBOType) {
GR_GL(GenFramebuffers(1, &rtIDs.fRTFBOID)); GR_GL(GenFramebuffers(1, &glRTDesc.fRTFBOID));
GrAssert(0 != rtIDs.fRTFBOID); GrAssert(0 != glRTDesc.fRTFBOID);
GR_GL(GenRenderbuffers(1, &rtIDs.fMSColorRenderbufferID)); GR_GL(GenRenderbuffers(1, &glRTDesc.fMSColorRenderbufferID));
GrAssert(0 != rtIDs.fMSColorRenderbufferID); GrAssert(0 != glRTDesc.fMSColorRenderbufferID);
if (!fboInternalFormat(desc.fFormat, &msColorRenderbufferFormat)) { if (!fboInternalFormat(desc.fFormat, &msColorRenderbufferFormat)) {
GR_GL(DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID)); GR_GL(DeleteRenderbuffers(1, &glRTDesc.fMSColorRenderbufferID));
GR_GL(DeleteTextures(1, &glDesc.fTextureID)); GR_GL(DeleteTextures(1, &glTexDesc.fTextureID));
GR_GL(DeleteFramebuffers(1, &rtIDs.fTexFBOID)); GR_GL(DeleteFramebuffers(1, &glRTDesc.fTexFBOID));
GR_GL(DeleteFramebuffers(1, &rtIDs.fRTFBOID)); GR_GL(DeleteFramebuffers(1, &glRTDesc.fRTFBOID));
return return_null_texture(); return return_null_texture();
} }
} else { } else {
rtIDs.fRTFBOID = rtIDs.fTexFBOID; glRTDesc.fRTFBOID = glRTDesc.fTexFBOID;
} }
if (!(kNoStencil_GrTextureFlagBit & desc.fFlags)) { if (!(kNoStencil_GrTextureFlagBit & desc.fFlags)) {
GR_GL(GenRenderbuffers(1, &rtIDs.fStencilRenderbufferID)); GR_GL(GenRenderbuffers(1, &glRTDesc.fStencilRenderbufferID));
GrAssert(0 != rtIDs.fStencilRenderbufferID); GrAssert(0 != glRTDesc.fStencilRenderbufferID);
} }
// someone suggested that some systems might require // someone suggested that some systems might require
@ -1167,7 +1178,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
err = ~GR_GL_NO_ERROR; err = ~GR_GL_NO_ERROR;
int stencilFmtCnt; int stencilFmtCnt;
if (rtIDs.fStencilRenderbufferID) { if (glRTDesc.fStencilRenderbufferID) {
stencilFmtCnt = fStencilFormats.count(); stencilFmtCnt = fStencilFormats.count();
} else { } else {
stencilFmtCnt = 1; // only 1 attempt when we don't need a stencil stencilFmtCnt = 1; // only 1 attempt when we don't need a stencil
@ -1179,43 +1190,43 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
// first (painful) stencil creation. // first (painful) stencil creation.
int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt; int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
if (rtIDs.fStencilRenderbufferID) { if (glRTDesc.fStencilRenderbufferID) {
GR_GL(BindRenderbuffer(GR_GL_RENDERBUFFER, GR_GL(BindRenderbuffer(GR_GL_RENDERBUFFER,
rtIDs.fStencilRenderbufferID)); glRTDesc.fStencilRenderbufferID));
if (samples > 1) { if (samples > 1) {
GR_GL_NO_ERR(RenderbufferStorageMultisample( GR_GL_NO_ERR(RenderbufferStorageMultisample(
GR_GL_RENDERBUFFER, GR_GL_RENDERBUFFER,
samples, samples,
fStencilFormats[sIdx].fEnum, fStencilFormats[sIdx].fEnum,
glDesc.fAllocWidth, glTexDesc.fAllocWidth,
glDesc.fAllocHeight)); glTexDesc.fAllocHeight));
} else { } else {
GR_GL_NO_ERR(RenderbufferStorage(GR_GL_RENDERBUFFER, GR_GL_NO_ERR(RenderbufferStorage(GR_GL_RENDERBUFFER,
fStencilFormats[sIdx].fEnum, fStencilFormats[sIdx].fEnum,
glDesc.fAllocWidth, glTexDesc.fAllocWidth,
glDesc.fAllocHeight)); glTexDesc.fAllocHeight));
} }
err = GrGLGetGLInterface()->fGetError(); err = GrGLGetGLInterface()->fGetError();
if (err != GR_GL_NO_ERROR) { if (err != GR_GL_NO_ERROR) {
continue; continue;
} }
} }
if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) { if (glRTDesc.fRTFBOID != glRTDesc.fTexFBOID) {
GrAssert(samples > 1); GrAssert(samples > 1);
GR_GL(BindRenderbuffer(GR_GL_RENDERBUFFER, GR_GL(BindRenderbuffer(GR_GL_RENDERBUFFER,
rtIDs.fMSColorRenderbufferID)); glRTDesc.fMSColorRenderbufferID));
GR_GL_NO_ERR(RenderbufferStorageMultisample( GR_GL_NO_ERR(RenderbufferStorageMultisample(
GR_GL_RENDERBUFFER, GR_GL_RENDERBUFFER,
samples, samples,
msColorRenderbufferFormat, msColorRenderbufferFormat,
glDesc.fAllocWidth, glTexDesc.fAllocWidth,
glDesc.fAllocHeight)); glTexDesc.fAllocHeight));
err = GrGLGetGLInterface()->fGetError(); err = GrGLGetGLInterface()->fGetError();
if (err != GR_GL_NO_ERROR) { if (err != GR_GL_NO_ERROR) {
continue; continue;
} }
} }
GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, rtIDs.fTexFBOID)); GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRTDesc.fTexFBOID));
#if GR_COLLECT_STATS #if GR_COLLECT_STATS
++fStats.fRenderTargetChngCnt; ++fStats.fRenderTargetChngCnt;
@ -1223,42 +1234,42 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GR_GL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0, GR_GL_COLOR_ATTACHMENT0,
GR_GL_TEXTURE_2D, GR_GL_TEXTURE_2D,
glDesc.fTextureID, 0)); glTexDesc.fTextureID, 0));
if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) { if (glRTDesc.fRTFBOID != glRTDesc.fTexFBOID) {
GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) { if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
continue; continue;
} }
GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, rtIDs.fRTFBOID)); GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRTDesc.fRTFBOID));
#if GR_COLLECT_STATS #if GR_COLLECT_STATS
++fStats.fRenderTargetChngCnt; ++fStats.fRenderTargetChngCnt;
#endif #endif
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0, GR_GL_COLOR_ATTACHMENT0,
GR_GL_RENDERBUFFER, GR_GL_RENDERBUFFER,
rtIDs.fMSColorRenderbufferID)); glRTDesc.fMSColorRenderbufferID));
} }
if (rtIDs.fStencilRenderbufferID) { if (glRTDesc.fStencilRenderbufferID) {
// bind the stencil to rt fbo if present, othewise the tex fbo // bind the stencil to rt fbo if present, othewise the tex fbo
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_STENCIL_ATTACHMENT, GR_GL_STENCIL_ATTACHMENT,
GR_GL_RENDERBUFFER, GR_GL_RENDERBUFFER,
rtIDs.fStencilRenderbufferID)); glRTDesc.fStencilRenderbufferID));
// if it is a packed format bind to depth also, otherwise // if it is a packed format bind to depth also, otherwise
// we may get an unsupported fbo completeness result // we may get an unsupported fbo completeness result
if (fStencilFormats[sIdx].fPacked) { if (fStencilFormats[sIdx].fPacked) {
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_DEPTH_ATTACHMENT, GR_GL_DEPTH_ATTACHMENT,
GR_GL_RENDERBUFFER, GR_GL_RENDERBUFFER,
rtIDs.fStencilRenderbufferID)); glRTDesc.fStencilRenderbufferID));
} }
} }
status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) { if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
// undo the depth bind // undo the depth bind
if (rtIDs.fStencilRenderbufferID && if (glRTDesc.fStencilRenderbufferID &&
fStencilFormats[sIdx].fPacked) { fStencilFormats[sIdx].fPacked) {
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_DEPTH_ATTACHMENT, GR_GL_DEPTH_ATTACHMENT,
@ -1269,30 +1280,30 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
} }
// we're successful! // we're successful!
failed = false; failed = false;
if (rtIDs.fStencilRenderbufferID) { if (glRTDesc.fStencilRenderbufferID) {
fLastSuccessfulStencilFmtIdx = sIdx; fLastSuccessfulStencilFmtIdx = sIdx;
if (gUNKNOWN_BITCOUNT == fStencilFormats[sIdx].fBits) { if (gUNKNOWN_BITCOUNT == fStencilFormats[sIdx].fBits) {
GR_GL_GetIntegerv(GR_GL_STENCIL_BITS, (GrGLint*)&glDesc.fStencilBits); GR_GL_GetIntegerv(GR_GL_STENCIL_BITS, (GrGLint*)&glRTDesc.fStencilBits);
} else { } else {
glDesc.fStencilBits = fStencilFormats[sIdx].fBits; glRTDesc.fStencilBits = fStencilFormats[sIdx].fBits;
} }
} }
break; break;
} }
if (failed) { if (failed) {
if (rtIDs.fStencilRenderbufferID) { if (glRTDesc.fStencilRenderbufferID) {
GR_GL(DeleteRenderbuffers(1, &rtIDs.fStencilRenderbufferID)); GR_GL(DeleteRenderbuffers(1, &glRTDesc.fStencilRenderbufferID));
} }
if (rtIDs.fMSColorRenderbufferID) { if (glRTDesc.fMSColorRenderbufferID) {
GR_GL(DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID)); GR_GL(DeleteRenderbuffers(1, &glRTDesc.fMSColorRenderbufferID));
} }
if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) { if (glRTDesc.fRTFBOID != glRTDesc.fTexFBOID) {
GR_GL(DeleteFramebuffers(1, &rtIDs.fRTFBOID)); GR_GL(DeleteFramebuffers(1, &glRTDesc.fRTFBOID));
} }
if (rtIDs.fTexFBOID) { if (glRTDesc.fTexFBOID) {
GR_GL(DeleteFramebuffers(1, &rtIDs.fTexFBOID)); GR_GL(DeleteFramebuffers(1, &glRTDesc.fTexFBOID));
} }
GR_GL(DeleteTextures(1, &glDesc.fTextureID)); GR_GL(DeleteTextures(1, &glTexDesc.fTextureID));
return return_null_texture(); return return_null_texture();
} }
} }
@ -1300,9 +1311,9 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GrPrintf("--- new texture [%d] size=(%d %d) bpp=%d\n", GrPrintf("--- new texture [%d] size=(%d %d) bpp=%d\n",
tex->fTextureID, width, height, tex->fUploadByteCount); tex->fTextureID, width, height, tex->fUploadByteCount);
#endif #endif
GrGLTexture* tex = new GrGLTexture(this, glDesc, rtIDs, DEFAULT_PARAMS); if (renderTarget) {
GrGLTexture* tex = new GrGLTexture(this, glTexDesc,
if (0 != rtIDs.fTexFBOID) { glRTDesc, DEFAULT_PARAMS);
GrRenderTarget* rt = tex->asRenderTarget(); GrRenderTarget* rt = tex->asRenderTarget();
// We've messed with FBO state but may not have set the correct viewport // We've messed with FBO state but may not have set the correct viewport
// so just dirty the rendertarget state to force a resend. // so just dirty the rendertarget state to force a resend.
@ -1315,8 +1326,10 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
this->clearStencil(0, ~0); this->clearStencil(0, ~0);
fCurrDrawState.fRenderTarget = rtSave; fCurrDrawState.fRenderTarget = rtSave;
} }
return tex;
} else {
return new GrGLTexture(this, glTexDesc, DEFAULT_PARAMS);
} }
return tex;
} }
GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) { GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) {

Просмотреть файл

@ -199,6 +199,7 @@
], ],
'defines': [ 'defines': [
'GR_IMPLEMENTATION=1', 'GR_IMPLEMENTATION=1',
'GR_USE_PLATFORM_CREATE_SAMPLE_COUNT=1',
], ],
'conditions': [ 'conditions': [
[ 'skia_os == "linux"', { [ 'skia_os == "linux"', {

Просмотреть файл

@ -132,7 +132,8 @@ public:
desc.fWidth = SkScalarRound(win->width()); desc.fWidth = SkScalarRound(win->width());
desc.fHeight = SkScalarRound(win->height()); desc.fHeight = SkScalarRound(win->height());
desc.fConfig = kRGBA_8888_GrPixelConfig; desc.fConfig = kRGBA_8888_GrPixelConfig;
desc.fStencilBits = 8; GR_GL_GetIntegerv(GR_GL_STENCIL_BITS, &desc.fStencilBits);
GR_GL_GetIntegerv(GR_GL_SAMPLES, &desc.fSampleCnt);
GrGLint buffer; GrGLint buffer;
GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer); GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer);
desc.fPlatformRenderTarget = buffer; desc.fPlatformRenderTarget = buffer;