Exemplo n.º 1
0
bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, int width, int height, size_t rowBytes,
                               GrPixelConfig srcConfig, DrawPreference* drawPreference,
                               WritePixelTempDrawInfo* tempDrawInfo) {
    SkASSERT(drawPreference);
    SkASSERT(tempDrawInfo);
    SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);

    if (GrPixelConfigIsCompressed(dstSurface->desc().fConfig) &&
            dstSurface->desc().fConfig != srcConfig) {
        return false;
    }

    if (this->caps()->useDrawInsteadOfPartialRenderTargetWrite() &&
            SkToBool(dstSurface->asRenderTarget()) &&
            (width < dstSurface->width() || height < dstSurface->height())) {
        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
    }

    if (!this->onGetWritePixelsInfo(dstSurface, width, height, rowBytes, srcConfig, drawPreference,
                                    tempDrawInfo)) {
        return false;
    }

    // Check to see if we're going to request that the caller draw when drawing is not possible.
    if (!dstSurface->asRenderTarget() ||
            !this->caps()->isConfigTexturable(tempDrawInfo->fTempSurfaceDesc.fConfig)) {
        // If we don't have a fallback to a straight upload then fail.
        if (kRequireDraw_DrawPreference == *drawPreference ||
                !this->caps()->isConfigTexturable(srcConfig)) {
            return false;
        }
        *drawPreference = kNoDraw_DrawPreference;
    }
    return true;
}
Exemplo n.º 2
0
bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width,
                               int height, GrColorType srcColorType,
                               GrSRGBConversion srgbConversion, DrawPreference* drawPreference,
                               WritePixelTempDrawInfo* tempDrawInfo) {
    SkASSERT(drawPreference);
    SkASSERT(tempDrawInfo);
    SkASSERT(dstSurface);
    SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);

    GrPixelConfig tempSurfaceConfig = kUnknown_GrPixelConfig;
    // GrGpu::writePixels doesn't do any sRGB conversions, so we must draw if there is one.
    switch (srgbConversion) {
        case GrSRGBConversion::kNone:
            // We support writing just A to a RGBA. In that case there is no sRGB version of the
            // src format but we still want to succeed.
            if (GrColorTypeIsAlphaOnly(srcColorType)) {
                tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kNo);
            } else {
                tempSurfaceConfig = GrColorTypeToPixelConfig(
                        srcColorType, GrPixelConfigIsSRGBEncoded(dstSurface->config()));
            }
            break;
        case GrSRGBConversion::kLinearToSRGB:
            SkASSERT(this->caps()->srgbSupport());
            // This assert goes away when we start referring to CPU data using color type.
            tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kNo);
            // We don't currently support storing sRGB encoded data in a surface unless it is
            // an SRGB-encoded config. That is likely to change when we need to store sRGB encoded
            // data in 101010102 and F16 textures. We'll have to provoke the caller to do the
            // conversion in a shader.
            if (!GrPixelConfigIsSRGB(dstSurface->config())) {
                return false;
            }
            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
            break;
        case GrSRGBConversion::kSRGBToLinear:
            SkASSERT(this->caps()->srgbSupport());
            tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kYes);
            // Currently we don't expect to make a SRGB encoded surface and then succeed at
            // treating it as though it were linear and then convert to sRGB.
            if (GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(dstSurface->config())) {
                return false;
            }
            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
            break;
    }
    if (kUnknown_GrPixelConfig == tempSurfaceConfig) {
        return false;
    }

    // Default values for intermediate draws. The intermediate texture config matches the dst's
    // config, is approx sized to the write rect, no swizzling or sppofing of the src config.
    tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
    tempDrawInfo->fTempSurfaceDesc.fConfig = tempSurfaceConfig;
    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1;
    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
    tempDrawInfo->fWriteColorType = srcColorType;

    if (!this->onGetWritePixelsInfo(dstSurface, dstOrigin, width, height, srcColorType,
                                    drawPreference, tempDrawInfo)) {
        return false;
    }

    // Check to see if we're going to request that the caller draw when drawing is not possible.
    if (!dstSurface->asRenderTarget() ||
        !this->caps()->isConfigTexturable(tempDrawInfo->fTempSurfaceDesc.fConfig)) {
        // If we don't have a fallback to a straight upload then fail.
        if (kRequireDraw_DrawPreference == *drawPreference /*TODO ||
            !this->caps()->isConfigTexturable(srcConfig)*/) {
            return false;
        }
        *drawPreference = kNoDraw_DrawPreference;
    }
    return true;
}
Exemplo n.º 3
0
bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width,
                              int height, size_t rowBytes, GrColorType dstColorType,
                              GrSRGBConversion srgbConversion, DrawPreference* drawPreference,
                              ReadPixelTempDrawInfo* tempDrawInfo) {
    SkASSERT(drawPreference);
    SkASSERT(tempDrawInfo);
    SkASSERT(srcSurface);
    SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);

    // We currently do not support reading into the packed formats 565 or 4444 as they are not
    // required to have read back support on all devices and backends.
    if (GrColorType::kRGB_565 == dstColorType || GrColorType::kABGR_4444 == dstColorType) {
        return false;
    }

    GrPixelConfig tempSurfaceConfig = kUnknown_GrPixelConfig;
    // GrGpu::readPixels doesn't do any sRGB conversions, so we must draw if there is one.
    switch (srgbConversion) {
        case GrSRGBConversion::kNone:
            // We support reading from RGBA to just A. In that case there is no sRGB version of the
            // dst format but we still want to succeed.
            if (GrColorTypeIsAlphaOnly(dstColorType)) {
                tempSurfaceConfig = GrColorTypeToPixelConfig(dstColorType, GrSRGBEncoded::kNo);
            } else {
                tempSurfaceConfig = GrColorTypeToPixelConfig(
                        dstColorType, GrPixelConfigIsSRGBEncoded(srcSurface->config()));
            }
            break;
        case GrSRGBConversion::kLinearToSRGB:
            SkASSERT(this->caps()->srgbSupport());
            tempSurfaceConfig = GrColorTypeToPixelConfig(dstColorType, GrSRGBEncoded::kYes);
            // Currently we don't expect to make a SRGB encoded surface and then read data from it
            // such that we treat it as though it were linear and is then converted to sRGB.
            if (GrPixelConfigIsSRGB(srcSurface->config())) {
                return false;
            }
            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
            break;
        case GrSRGBConversion::kSRGBToLinear:
            SkASSERT(this->caps()->srgbSupport());
            tempSurfaceConfig = GrColorTypeToPixelConfig(dstColorType, GrSRGBEncoded::kNo);
            // We don't currently support reading sRGB encoded data into linear from a surface
            // unless it is an sRGB-encoded config. That is likely to change when we need to store
            // sRGB encoded data in 101010102 and F16 textures. We'll have to provoke the caller to
            // do the conversion in a shader.
            if (GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(srcSurface->config())) {
                return false;
            }
            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
            break;
    }
    if (kUnknown_GrPixelConfig == tempSurfaceConfig) {
        return false;
    }

    // Default values for intermediate draws. The intermediate texture config matches the dst's
    // config, is approx sized to the read rect, no swizzling or spoofing of the dst config.
    tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1;
    tempDrawInfo->fTempSurfaceDesc.fConfig = tempSurfaceConfig;
    tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox;
    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
    tempDrawInfo->fReadColorType = dstColorType;

    if (!this->onGetReadPixelsInfo(srcSurface, srcOrigin, width, height, rowBytes, dstColorType,
                                   drawPreference, tempDrawInfo)) {
        return false;
    }

    // Check to see if we're going to request that the caller draw when drawing is not possible.
    if (!srcSurface->asTexture() ||
        !this->caps()->isConfigRenderable(tempDrawInfo->fTempSurfaceDesc.fConfig)) {
        // If we don't have a fallback to a straight read then fail.
        if (kRequireDraw_DrawPreference == *drawPreference) {
            return false;
        }
        *drawPreference = kNoDraw_DrawPreference;
    }

    return true;
}