| 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));
|
|
|