Index: src/gpu/gl/GrGLGpu.cpp |
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp |
index e0b7d4aca5e2561df0249a8e81b4e41c3b5a50e4..f484fa541e88c52814b923512a9ff89e854e46ac 100644 |
--- a/src/gpu/gl/GrGLGpu.cpp |
+++ b/src/gpu/gl/GrGLGpu.cpp |
@@ -742,14 +742,14 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, |
#endif |
// Internal format comes from the texture desc. |
- GrGLenum internalFormat = |
- this->glCaps().configGLFormats(desc.fConfig).fInternalFormatTexImage; |
- |
+ GrGLenum internalFormat; |
// External format and type come from the upload data. |
- GrGLenum externalFormat = |
- this->glCaps().configGLFormats(dataConfig).fExternalFormatForTexImage; |
- GrGLenum externalType = this->glCaps().configGLFormats(dataConfig).fExternalType; |
- |
+ GrGLenum externalFormat; |
+ GrGLenum externalType; |
+ if (!this->glCaps().getTexImageFormats(desc.fConfig, dataConfig, &internalFormat, |
+ &externalFormat, &externalType)) { |
+ return false; |
+ } |
/* |
* Check whether to allocate a temporary buffer for flipping y or |
* because our srcData has extra bytes past each row. If so, we need |
@@ -811,7 +811,7 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, |
} else { |
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); |
GL_ALLOC_CALL(this->glInterface(), TexImage2D(target, 0, internalFormat, desc.fWidth, |
- desc.fHeight, 0, externalFormat, |
+ desc.fHeight, 0, externalFormat, |
externalType, dataOrOffset)); |
GrGLenum error = check_alloc_error(desc, this->glInterface()); |
if (error != GR_GL_NO_ERROR) { |
@@ -878,9 +878,11 @@ bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, |
// is a multiple of the block size. |
size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height); |
- // We only need the internal format for compressed 2D textures. There is on |
- // sized vs base internal format distinction for compressed textures. |
- GrGLenum internalFormat =this->glCaps().configGLFormats(desc.fConfig).fSizedInternalFormat; |
+ // We only need the internal format for compressed 2D textures. |
+ GrGLenum internalFormat; |
+ if (!this->glCaps().getCompressedTexImageFormats(desc.fConfig, &internalFormat)) { |
+ return false; |
+ } |
if (kNewTexture_UploadType == uploadType) { |
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); |
@@ -988,12 +990,9 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, |
!idDesc->fMSColorRenderbufferID) { |
goto FAILED; |
} |
- // All ES versions (thus far) require sized internal formats for render buffers. |
- // TODO: Always use sized internal format? |
- // If this rule gets more complicated, add a field to ConfigEntry rather than logic here. |
- colorRenderbufferFormat = kGLES_GrGLStandard == this->glStandard() ? |
- this->glCaps().configGLFormats(desc.fConfig).fSizedInternalFormat : |
- this->glCaps().configGLFormats(desc.fConfig).fBaseInternalFormat; |
+ if (!this->glCaps().getRenderbufferFormat(desc.fConfig, &colorRenderbufferFormat)) { |
+ return false; |
+ } |
} else { |
idDesc->fRTFBOID = idDesc->fTexFBOID; |
} |
@@ -1267,17 +1266,22 @@ int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) { |
GR_GL_TEXTURE_WRAP_T, |
GR_GL_CLAMP_TO_EDGE)); |
- const GrGLCaps::ConfigFormats colorFormats = this->glCaps().configGLFormats(config); |
- |
+ GrGLenum internalFormat; |
+ GrGLenum externalFormat; |
+ GrGLenum externalType; |
+ if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat, |
+ &externalType)) { |
+ return false; |
+ } |
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); |
GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, |
0, |
- colorFormats.fInternalFormatTexImage, |
+ internalFormat, |
kSize, |
kSize, |
0, |
- colorFormats.fExternalFormatForTexImage, |
- colorFormats.fExternalType, |
+ externalFormat, |
+ externalType, |
NULL)); |
if (GR_GL_NO_ERROR != CHECK_ALLOC_ERROR(this->glInterface())) { |
GL_CALL(DeleteTextures(1, &colorID)); |
@@ -1566,7 +1570,9 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) { |
} |
if (blendInfo.fWriteColor) { |
- this->flushBlend(blendInfo); |
+ const GrSwizzle& swizzle = |
+ this->glCaps().configSwizzle(args.fPipeline->getRenderTarget()->config()); |
+ this->flushBlend(blendInfo, swizzle); |
} |
SkSTArray<8, const GrTextureAccess*> textureAccesses; |
@@ -2016,8 +2022,12 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, |
return false; |
} |
- GrGLenum format = this->glCaps().configGLFormats(config).fExternalFormat; |
- GrGLenum type = this->glCaps().configGLFormats(config).fExternalType; |
+ GrGLenum externalFormat; |
+ GrGLenum externalType; |
+ if (!this->glCaps().getReadPixelsFormat(surface->config(), config, &externalFormat, |
+ &externalType)) { |
+ return false; |
+ } |
bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); |
// resolve the render target if necessary |
@@ -2038,6 +2048,26 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, |
SkFAIL("Unknown resolve type"); |
} |
+ // This must be called after the RT is bound as the FBO above. |
+ if (!this->glCaps().readPixelsSupported(this->glInterface(), config, tgt->config())) { |
+ if ((tgt->config() == kRGBA_8888_GrPixelConfig || |
+ tgt->config() == kBGRA_8888_GrPixelConfig) && |
+ kAlpha_8_GrPixelConfig == config) { |
+ SkAutoTDeleteArray<uint32_t> temp(new uint32_t[width * height * 4]); |
+ if (this->onReadPixels(surface, left, top, width, height, kRGBA_8888_GrPixelConfig, |
+ temp.get(), width*4)) { |
+ uint8_t* dst = reinterpret_cast<uint8_t*>(buffer); |
+ for (int j = 0; j < height; ++j) { |
+ for (int i = 0; i < width; ++i) { |
+ dst[j*rowBytes + i] = (0xFF000000U & temp[j*width+i]) >> 24; |
+ } |
+ } |
+ return true; |
+ } |
+ } |
+ return false; |
+ } |
+ |
const GrGLIRect& glvp = tgt->getViewport(); |
// the read rect is viewport-relative |
@@ -2070,7 +2100,7 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, |
GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom, |
readRect.fWidth, readRect.fHeight, |
- format, type, readDst)); |
+ externalFormat, externalType, readDst)); |
if (readDstRowBytes != tightRowBytes) { |
SkASSERT(this->glCaps().packRowLengthSupport()); |
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); |
@@ -2387,7 +2417,7 @@ void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA) { |
} |
} |
-void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo) { |
+void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) { |
// Any optimization to disable blending should have already been applied and |
// tweaked the equation to "add" or "subtract", and the coeffs to (1, 0). |
@@ -2440,16 +2470,16 @@ void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo) { |
fHWBlendState.fDstCoeff = dstCoeff; |
} |
- GrColor blendConst = blendInfo.fBlendConstant; |
- if ((BlendCoeffReferencesConstant(srcCoeff) || |
- BlendCoeffReferencesConstant(dstCoeff)) && |
- (!fHWBlendState.fConstColorValid || |
- fHWBlendState.fConstColor != blendConst)) { |
- GrGLfloat c[4]; |
- GrColorToRGBAFloat(blendConst, c); |
- GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); |
- fHWBlendState.fConstColor = blendConst; |
- fHWBlendState.fConstColorValid = true; |
+ if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff))) { |
+ GrColor blendConst = blendInfo.fBlendConstant; |
+ swizzle.applyTo(blendConst); |
+ if (!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst) { |
+ GrGLfloat c[4]; |
+ GrColorToRGBAFloat(blendConst, c); |
+ GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); |
+ fHWBlendState.fConstColor = blendConst; |
+ fHWBlendState.fConstColorValid = true; |
+ } |
} |
} |
@@ -3107,7 +3137,7 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor |
GrXferProcessor::BlendInfo blendInfo; |
blendInfo.reset(); |
- this->flushBlend(blendInfo); |
+ this->flushBlend(blendInfo, GrSwizzle::RGBA()); |
this->flushColorWrite(true); |
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
this->flushHWAAState(glRT, false); |
@@ -3178,7 +3208,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, |
GrXferProcessor::BlendInfo blendInfo; |
blendInfo.reset(); |
- this->flushBlend(blendInfo); |
+ this->flushBlend(blendInfo, GrSwizzle::RGBA()); |
this->flushColorWrite(true); |
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
this->flushHWAAState(dstRT, false); |
@@ -3326,9 +3356,19 @@ GrBackendObject GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, in |
GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE)); |
GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE)); |
- GrGLenum internalFormat = this->glCaps().configGLFormats(config).fInternalFormatTexImage; |
- GrGLenum externalFormat = this->glCaps().configGLFormats(config).fExternalFormatForTexImage; |
- GrGLenum externalType = this->glCaps().configGLFormats(config).fExternalType; |
+ GrGLenum internalFormat; |
+ GrGLenum externalFormat; |
+ GrGLenum externalType; |
+ |
+ if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat, |
+ &externalType)) { |
+ delete info; |
+#ifdef SK_IGNORE_GL_TEXTURE_TARGET |
+ return 0; |
+#else |
+ return reinterpret_cast<GrBackendObject>(nullptr); |
+#endif |
+ } |
GL_CALL(TexImage2D(info->fTarget, 0, internalFormat, w, h, 0, externalFormat, |
externalType, pixels)); |