Add support for GL_EXT_unpack_subimage
Review URL: http://codereview.appspot.com/5359048/ git-svn-id: http://skia.googlecode.com/svn/trunk@2654 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
3d3dfe011c
commit
7107fa789a
@ -222,14 +222,6 @@ extern void GrGLClearErr(const GrGLInterface* gl);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* GrGLResetRowLength() will reset GL_UNPACK_ROW_LENGTH to 0. We write
|
||||
* this wrapper, since GL_UNPACK_ROW_LENGTH is not available on all GL versions
|
||||
*/
|
||||
extern void GrGLResetRowLength(const GrGLInterface*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Some drivers want the var-int arg to be zero-initialized on input.
|
||||
*/
|
||||
|
@ -133,12 +133,12 @@ void GrGLTexture::uploadTextureData(int x,
|
||||
/*
|
||||
* check whether to allocate a temporary buffer for flipping y or
|
||||
* because our srcData has extra bytes past each row. If so, we need
|
||||
* to trim those off here, since GL ES doesn't let us specify
|
||||
* to trim those off here, since GL ES may not let us specify
|
||||
* GL_UNPACK_ROW_LENGTH.
|
||||
*/
|
||||
bool restoreGLRowLength = false;
|
||||
bool flipY = kBottomUp_Orientation == fOrientation;
|
||||
if (kDesktop_GrGLBinding == GPUGL->glBinding() && !flipY) {
|
||||
if (GPUGL->glCaps().fUnpackRowLengthSupport && !flipY) {
|
||||
// can't use this for flipping, only non-neg values allowed. :(
|
||||
if (srcData && rowBytes != trimRowBytes) {
|
||||
GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
|
||||
@ -176,10 +176,9 @@ void GrGLTexture::uploadTextureData(int x,
|
||||
GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
|
||||
fUploadFormat, fUploadType, srcData));
|
||||
|
||||
if (kDesktop_GrGLBinding == GPUGL->glBinding()) {
|
||||
if (restoreGLRowLength) {
|
||||
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
|
||||
}
|
||||
if (restoreGLRowLength) {
|
||||
GrAssert(GPUGL->glCaps().fUnpackRowLengthSupport);
|
||||
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,12 +30,6 @@ void GrGLCheckErr(const GrGLInterface* gl,
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLResetRowLength(const GrGLInterface* gl) {
|
||||
if (gl->supportsDesktop()) {
|
||||
GR_GL_CALL(gl, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if GR_GL_LOG_CALLS
|
||||
|
@ -382,33 +382,43 @@ void GrGpuGL::initCaps() {
|
||||
}
|
||||
|
||||
if (kDesktop_GrGLBinding == this->glBinding()) {
|
||||
fGLCaps.fRGBA8Renderbuffer = true;
|
||||
fGLCaps.fRGBA8RenderbufferSupport = true;
|
||||
} else {
|
||||
fGLCaps.fRGBA8Renderbuffer = this->hasExtension("GL_OES_rgb8_rgba8") ||
|
||||
this->hasExtension("GL_ARM_rgba8");
|
||||
fGLCaps.fRGBA8RenderbufferSupport =
|
||||
this->hasExtension("GL_OES_rgb8_rgba8") ||
|
||||
this->hasExtension("GL_ARM_rgba8");
|
||||
}
|
||||
|
||||
|
||||
if (kDesktop_GrGLBinding == this->glBinding()) {
|
||||
fGLCaps.fBGRAFormat = this->glVersion() >= GR_GL_VER(1,2) ||
|
||||
this->hasExtension("GL_EXT_bgra");
|
||||
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.fBGRAFormat = true;
|
||||
fGLCaps.fBGRAFormatSupport = true;
|
||||
} else if (this->hasExtension("GL_EXT_texture_format_BGRA8888")) {
|
||||
fGLCaps.fBGRAFormat = true;
|
||||
fGLCaps.fBGRAInternalFormat = true;
|
||||
fGLCaps.fBGRAFormatSupport = true;
|
||||
fGLCaps.fBGRAIsInternalFormat = true;
|
||||
}
|
||||
GrAssert(fGLCaps.fBGRAFormat ||
|
||||
GrAssert(fGLCaps.fBGRAFormatSupport ||
|
||||
kSkia8888_PM_GrPixelConfig != kBGRA_8888_PM_GrPixelConfig);
|
||||
}
|
||||
|
||||
if (kDesktop_GrGLBinding == this->glBinding()) {
|
||||
fGLCaps.fTextureSwizzle = this->glVersion() >= GR_GL_VER(3,3) ||
|
||||
fGLCaps.fTextureSwizzleSupport = this->glVersion() >= GR_GL_VER(3,3) ||
|
||||
this->hasExtension("GL_ARB_texture_swizzle");
|
||||
} else {
|
||||
fGLCaps.fTextureSwizzle = false;
|
||||
fGLCaps.fTextureSwizzleSupport = false;
|
||||
}
|
||||
|
||||
if (kDesktop_GrGLBinding == this->glBinding()) {
|
||||
fGLCaps.fUnpackRowLengthSupport = true;
|
||||
fGLCaps.fPackRowLengthSupport = true;
|
||||
} else {
|
||||
fGLCaps.fUnpackRowLengthSupport = this->hasExtension("GL_EXT_unpack_subimage");
|
||||
// no extension for pack row length
|
||||
fGLCaps.fPackRowLengthSupport = false;
|
||||
}
|
||||
|
||||
if (kDesktop_GrGLBinding == this->glBinding()) {
|
||||
@ -836,7 +846,7 @@ void GrGpuGL::allocateAndUploadTexData(const GrGLTexture::Desc& desc,
|
||||
* GL_UNPACK_ROW_LENGTH.
|
||||
*/
|
||||
bool flipY = GrGLTexture::kBottomUp_Orientation == desc.fOrientation;
|
||||
if (kDesktop_GrGLBinding == this->glBinding() && !flipY) {
|
||||
if (this->glCaps().fUnpackRowLengthSupport && !flipY) {
|
||||
if (data && rowBytes != trimRowBytes) {
|
||||
GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
|
||||
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
|
||||
@ -876,7 +886,9 @@ void GrGpuGL::allocateAndUploadTexData(const GrGLTexture::Desc& desc,
|
||||
GL_CALL(CompressedTexImage2D(GR_GL_TEXTURE_2D, 0, desc.fUploadFormat,
|
||||
desc.fAllocWidth, desc.fAllocHeight,
|
||||
0, imageSize, data));
|
||||
GrGLResetRowLength(this->glInterface());
|
||||
if (this->glCaps().fUnpackRowLengthSupport) {
|
||||
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
|
||||
}
|
||||
} else {
|
||||
if (NULL != data && (desc.fAllocWidth != desc.fContentWidth ||
|
||||
desc.fAllocHeight != desc.fContentHeight)) {
|
||||
@ -886,7 +898,9 @@ void GrGpuGL::allocateAndUploadTexData(const GrGLTexture::Desc& desc,
|
||||
GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, 0, 0, desc.fContentWidth,
|
||||
desc.fContentHeight, desc.fUploadFormat,
|
||||
desc.fUploadType, data));
|
||||
GrGLResetRowLength(this->glInterface());
|
||||
if (this->glCaps().fUnpackRowLengthSupport) {
|
||||
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
|
||||
}
|
||||
|
||||
int extraW = desc.fAllocWidth - desc.fContentWidth;
|
||||
int extraH = desc.fAllocHeight - desc.fContentHeight;
|
||||
@ -943,7 +957,9 @@ void GrGpuGL::allocateAndUploadTexData(const GrGLTexture::Desc& desc,
|
||||
GL_CALL(TexImage2D(GR_GL_TEXTURE_2D, 0, internalFormat,
|
||||
desc.fAllocWidth, desc.fAllocHeight, 0,
|
||||
desc.fUploadFormat, desc.fUploadType, data));
|
||||
GrGLResetRowLength(this->glInterface());
|
||||
if (this->glCaps().fUnpackRowLengthSupport) {
|
||||
GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1485,14 +1501,11 @@ bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
|
||||
int width, int height,
|
||||
GrPixelConfig config,
|
||||
size_t rowBytes) {
|
||||
if (kDesktop_GrGLBinding == this->glBinding()) {
|
||||
return false;
|
||||
} else {
|
||||
// On ES we'll have to do memcpys to handle rowByte padding. So, we
|
||||
// might as well flipY while we're at it.
|
||||
return 0 == rowBytes ||
|
||||
GrBytesPerPixel(config) * width == rowBytes;
|
||||
}
|
||||
// if we have to do memcpy to handle non-trim rowBytes then we
|
||||
// get the flip for free. Otherwise it costs.
|
||||
return this->glCaps().fPackRowLengthSupport ||
|
||||
0 == rowBytes ||
|
||||
GrBytesPerPixel(config) * width == rowBytes;
|
||||
}
|
||||
|
||||
bool GrGpuGL::onReadPixels(GrRenderTarget* target,
|
||||
@ -1547,7 +1560,7 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
|
||||
// a scratch buffer.
|
||||
SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
|
||||
if (rowBytes != tightRowBytes) {
|
||||
if (kDesktop_GrGLBinding == this->glBinding()) {
|
||||
if (this->glCaps().fPackRowLengthSupport) {
|
||||
GrAssert(!(rowBytes % sizeof(GrColor)));
|
||||
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowBytes / sizeof(GrColor)));
|
||||
readDstRowBytes = rowBytes;
|
||||
@ -1560,6 +1573,7 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
|
||||
readRect.fWidth, readRect.fHeight,
|
||||
format, type, readDst));
|
||||
if (readDstRowBytes != tightRowBytes) {
|
||||
GrAssert(this->glCaps().fPackRowLengthSupport);
|
||||
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
|
||||
}
|
||||
|
||||
@ -2155,7 +2169,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
||||
GR_GL_TEXTURE_WRAP_T,
|
||||
newTexParams.fWrapT));
|
||||
}
|
||||
if (this->glCaps().fTextureSwizzle &&
|
||||
if (this->glCaps().fTextureSwizzleSupport &&
|
||||
(setAll ||
|
||||
memcmp(newTexParams.fSwizzleRGBA,
|
||||
oldTexParams.fSwizzleRGBA,
|
||||
@ -2297,11 +2311,11 @@ bool GrGpuGL::canBeTexture(GrPixelConfig config,
|
||||
break;
|
||||
case kBGRA_8888_PM_GrPixelConfig:
|
||||
case kBGRA_8888_UPM_GrPixelConfig:
|
||||
if (!fGLCaps.fBGRAFormat) {
|
||||
if (!fGLCaps.fBGRAFormatSupport) {
|
||||
return false;
|
||||
}
|
||||
*format = GR_GL_BGRA;
|
||||
if (fGLCaps.fBGRAInternalFormat) {
|
||||
if (fGLCaps.fBGRAIsInternalFormat) {
|
||||
*internalFormat = GR_GL_BGRA;
|
||||
} else {
|
||||
*internalFormat = GR_GL_RGBA;
|
||||
@ -2374,7 +2388,7 @@ bool GrGpuGL::fboInternalFormat(GrPixelConfig config, GrGLenum* format) {
|
||||
case kRGBA_8888_UPM_GrPixelConfig:
|
||||
case kBGRA_8888_PM_GrPixelConfig:
|
||||
case kBGRA_8888_UPM_GrPixelConfig:
|
||||
if (fGLCaps.fRGBA8Renderbuffer) {
|
||||
if (fGLCaps.fRGBA8RenderbufferSupport) {
|
||||
// The GL_OES_rgba8_rgb8 extension defines GL_RGBA8 as a sized
|
||||
// internal format.
|
||||
*format = GR_GL_RGBA8;
|
||||
@ -2497,9 +2511,13 @@ void GrGpuGL::GLCaps::print() const {
|
||||
}
|
||||
GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
|
||||
GrPrintf("Support RGBA8 Render Buffer: %s\n",
|
||||
(fRGBA8Renderbuffer ? "YES": "NO"));
|
||||
(fRGBA8RenderbufferSupport ? "YES": "NO"));
|
||||
GrPrintf("BGRA is an internal format: %s\n",
|
||||
(fBGRAInternalFormat ? "YES": "NO"));
|
||||
(fBGRAIsInternalFormat ? "YES": "NO"));
|
||||
GrPrintf("Support texture swizzle: %s\n",
|
||||
(fTextureSwizzle ? "YES": "NO"));
|
||||
(fTextureSwizzleSupport ? "YES": "NO"));
|
||||
GrPrintf("Unpack Row length support: %s\n",
|
||||
(fUnpackRowLengthSupport ? "YES": "NO"));
|
||||
GrPrintf("Pack Row length support: %s\n",
|
||||
(fPackRowLengthSupport ? "YES": "NO"));
|
||||
}
|
||||
|
@ -48,10 +48,12 @@ protected:
|
||||
: fStencilFormats(8) // prealloc space for stencil formats
|
||||
, fMSFBOType(kNone_MSFBO)
|
||||
, fMaxFragmentUniformVectors(0)
|
||||
, fRGBA8Renderbuffer(false)
|
||||
, fBGRAFormat(false)
|
||||
, fBGRAInternalFormat(false)
|
||||
, fTextureSwizzle(false) {
|
||||
, fRGBA8RenderbufferSupport(false)
|
||||
, fBGRAFormatSupport(false)
|
||||
, fBGRAIsInternalFormat(false)
|
||||
, fTextureSwizzleSupport(false)
|
||||
, fUnpackRowLengthSupport(false)
|
||||
, fPackRowLengthSupport(false) {
|
||||
memset(fAASamples, 0, sizeof(fAASamples));
|
||||
}
|
||||
SkTArray<GrGLStencilBuffer::Format, true> fStencilFormats;
|
||||
@ -82,19 +84,25 @@ protected:
|
||||
int fMaxFragmentUniformVectors;
|
||||
|
||||
// ES requires an extension to support RGBA8 in RenderBufferStorage
|
||||
bool fRGBA8Renderbuffer;
|
||||
bool fRGBA8RenderbufferSupport;
|
||||
|
||||
// Is GL_BGRA supported
|
||||
bool fBGRAFormat;
|
||||
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 fBGRAInternalFormat;
|
||||
bool fBGRAIsInternalFormat;
|
||||
|
||||
// GL_ARB_texture_swizzle support
|
||||
bool fTextureSwizzle;
|
||||
bool fTextureSwizzleSupport;
|
||||
|
||||
// Is there support for GL_UNPACK_ROW_LENGTH
|
||||
bool fUnpackRowLengthSupport;
|
||||
|
||||
// Is there support for GL_PACK_ROW_LENGTH
|
||||
bool fPackRowLengthSupport;
|
||||
|
||||
void print() const;
|
||||
} fGLCaps;
|
||||
|
||||
|
@ -1001,7 +1001,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
stage.fOptFlags |= StageDesc::kCustomTextureDomain_OptFlagBit;
|
||||
}
|
||||
|
||||
if (!this->glCaps().fTextureSwizzle) {
|
||||
if (!this->glCaps().fTextureSwizzleSupport) {
|
||||
if (GrPixelConfigIsAlphaOnly(texture->config())) {
|
||||
// if we don't have texture swizzle support then
|
||||
// the shader must do an alpha smear after reading
|
||||
|
Loading…
Reference in New Issue
Block a user