Example #1
0
DEF_GPUTEST_FOR_NATIVE_CONTEXT(SkImage_newTextureImage, reporter, context, glContext) {
    GrContextFactory otherFactory;
    GrContextFactory::ContextInfo otherContextInfo =
        otherFactory.getContextInfo(GrContextFactory::kNative_GLContextType);
    glContext->makeCurrent();

    std::function<SkImage*()> imageFactories[] = {
        create_image,
        create_codec_image,
        create_data_image,
        // Create an image from a picture.
        create_picture_image,
        // Create a texture image.
        [context] { return create_gpu_image(context); },
        // Create a texture image in a another GrContext.
        [glContext, otherContextInfo] {
            otherContextInfo.fGLContext->makeCurrent();
            SkImage* otherContextImage = create_gpu_image(otherContextInfo.fGrContext);
            glContext->makeCurrent();
            return otherContextImage;
        }
    };

    for (auto factory : imageFactories) {
        SkAutoTUnref<SkImage> image(factory());
        if (!image) {
            ERRORF(reporter, "Error creating image.");
            continue;
        }
        GrTexture* origTexture = as_IB(image)->peekTexture();

        SkAutoTUnref<SkImage> texImage(image->newTextureImage(context));
        if (!texImage) {
            // We execpt to fail if image comes from a different GrContext.
            if (!origTexture || origTexture->getContext() == context) {
                ERRORF(reporter, "newTextureImage failed.");
            }
            continue;
        }
        GrTexture* copyTexture = as_IB(texImage)->peekTexture();
        if (!copyTexture) {
            ERRORF(reporter, "newTextureImage returned non-texture image.");
            continue;
        }
        if (origTexture) {
            if (origTexture != copyTexture) {
                ERRORF(reporter, "newTextureImage made unnecessary texture copy.");
            }
        }
        if (image->width() != texImage->width() || image->height() != texImage->height()) {
            ERRORF(reporter, "newTextureImage changed the image size.");
        }
        if (image->isOpaque() != texImage->isOpaque()) {
            ERRORF(reporter, "newTextureImage changed image opaqueness.");
        }
    }
}
Example #2
0
SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec,
                                                    SkArenaAlloc* alloc) const {
    const auto info = as_IB(fImage)->onImageInfo();

    if (info.colorType() != kN32_SkColorType) {
        return nullptr;
    }
    if (info.alphaType() == kUnpremul_SkAlphaType) {
        return nullptr;
    }
#ifndef SK_SUPPORT_LEGACY_TILED_BITMAPS
    if (fTileModeX != fTileModeY) {
        return nullptr;
    }
#endif
    if (fTileModeX == kDecal_TileMode || fTileModeY == kDecal_TileMode) {
        return nullptr;
    }

    SkMatrix inv;
    if (!this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, &inv) ||
        !legacy_shader_can_handle(inv)) {
        return nullptr;
    }

    return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY,
                                                 SkBitmapProvider(fImage.get(), rec.fDstColorSpace),
                                                 rec, alloc);
}
Example #3
0
SkImageInfo SkBitmapProvider::info() const {
    if (fImage) {
        return as_IB(fImage)->onImageInfo();
    } else {
        return fBitmap.info();
    }
}
Example #4
0
SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const {
    SkBitmap bm;
    if (as_IB(this)->getROPixels(&bm)) {
        return SkImageEncoder::EncodeData(bm, type, quality);
    }
    return NULL;
}
Example #5
0
sk_sp<SkImage> SkImage::makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
                                       const SkIRect& clipBounds, SkIRect* outSubset,
                                       SkIPoint* offset) const {
    if (!filter || !outSubset || !offset || !this->bounds().contains(subset)) {
        return nullptr;
    }
    SkColorSpace* colorSpace = as_IB(this)->onImageInfo().colorSpace();
    sk_sp<SkSpecialImage> srcSpecialImage = SkSpecialImage::MakeFromImage(
        subset, sk_ref_sp(const_cast<SkImage*>(this)), colorSpace);
    if (!srcSpecialImage) {
        return nullptr;
    }

    sk_sp<SkImageFilterCache> cache(
        SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize));
    SkImageFilter::OutputProperties outputProperties(colorSpace);
    SkImageFilter::Context context(SkMatrix::I(), clipBounds, cache.get(), outputProperties);

    sk_sp<SkSpecialImage> result = filter->filterImage(srcSpecialImage.get(), context, offset);
    if (!result) {
        return nullptr;
    }

    *outSubset = SkIRect::MakeWH(result->width(), result->height());
    if (!outSubset->intersect(clipBounds.makeOffset(-offset->x(), -offset->y()))) {
        return nullptr;
    }
    offset->fX += outSubset->x();
    offset->fY += outSubset->y();

    // Note that here we're returning the special image's entire backing store, loose padding
    // and all!
    return result->asImage();
}
Example #6
0
void SkBitmapProvider::notifyAddedToCache() const {
    if (fImage) {
        as_IB(fImage)->notifyAddedToCache();
    } else {
        fBitmap.pixelRef()->notifyAddedToCache();
    }
}
Example #7
0
    GrTexture* onAsTextureRef(GrContext* context) const override {
#if SK_SUPPORT_GPU
        return as_IB(fImage)->asTextureRef(context, GrTextureParams::ClampNoFilter());
#else
        return nullptr;
#endif
    }
Example #8
0
void WindowContext::presentRenderSurface(sk_sp<SkSurface> renderSurface, sk_sp<GrRenderTarget> rt,
                                         int colorBits) {
    if (!this->isGpuContext() || colorBits > 24 ||
        kRGBA_F16_SkColorType == fDisplayParams.fColorType) {
        // We made/have an off-screen surface. Get the contents as an SkImage:
        SkImageInfo info = SkImageInfo::Make(fWidth, fHeight,
                                             fDisplayParams.fColorType,
                                             kUnknown_SkAlphaType,
                                             fDisplayParams.fColorSpace);
        SkBitmap bm;
        bm.allocPixels(info);
        renderSurface->getCanvas()->readPixels(&bm, 0, 0);
        SkPixmap pm;
        bm.peekPixels(&pm);
        sk_sp<SkImage> image(SkImage::MakeTextureFromPixmap(fContext, pm,
                             SkBudgeted::kNo));
        GrTexture* texture = as_IB(image)->peekTexture();
        SkASSERT(texture);

        // With ten-bit output, we need to manually apply the gamma of the output device
        // (unless we're in non-gamma correct mode, in which case our data is already
        // fake-sRGB, like we're expected to put in the 10-bit buffer):
        bool doGamma = (colorBits == 30) && SkImageInfoIsGammaCorrect(info);
        fContext->applyGamma(rt.get(), texture, doGamma ? 1.0f / 2.2f : 1.0f);
    }
}
Example #9
0
bool SkImage::peekPixels(SkPixmap* pm) const {
    SkPixmap tmp;
    if (!pm) {
        pm = &tmp;
    }
    return as_IB(this)->onPeekPixels(pm);
}
Example #10
0
sk_sp<SkImage> SkImageMakeRasterCopyAndAssignColorSpace(const SkImage* src,
                                                        SkColorSpace* colorSpace) {
    // Read the pixels out of the source image, with no conversion
    SkImageInfo info = as_IB(src)->onImageInfo();
    if (kUnknown_SkColorType == info.colorType()) {
        SkDEBUGFAIL("Unexpected color type");
        return nullptr;
    }

    size_t rowBytes = info.minRowBytes();
    size_t size = info.computeByteSize(rowBytes);
    if (SkImageInfo::ByteSizeOverflowed(size)) {
        return nullptr;
    }
    auto data = SkData::MakeUninitialized(size);
    if (!data) {
        return nullptr;
    }

    SkPixmap pm(info, data->writable_data(), rowBytes);
    if (!src->readPixels(pm, 0, 0, SkImage::kDisallow_CachingHint)) {
        return nullptr;
    }

    // Wrap them in a new image with a different color space
    return SkImage::MakeRasterData(info.makeColorSpace(sk_ref_sp(colorSpace)), data, rowBytes);
}
Example #11
0
void SkBaseDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
                             const SkPaint& paint) {
    SkBitmap bm;
    if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
        this->drawBitmap(bm, x, y, paint);
    }
}
Example #12
0
bool SkBitmapProvider::asBitmap(SkBitmap* bm) const {
    if (fImage) {
        return as_IB(fImage)->getROPixels(bm);
    } else {
        *bm = fBitmap;
        return true;
    }
}
Example #13
0
GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client,
                                                 bool useDecal)
    : INHERITED(context, client->width(), client->height(), client->isAlphaOnly(), useDecal)
    , fImage(static_cast<const SkImage_GpuYUVA*>(client)) {
    SkASSERT(as_IB(client)->isYUVA());
    GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(),
                         SkIRect::MakeWH(this->width(), this->height()));
}
Example #14
0
sk_sp<SkData> SkImage::encodeToData(SkEncodedImageFormat type, int quality) const {
    SkBitmap bm;
    SkColorSpace* legacyColorSpace = nullptr;
    if (as_IB(this)->getROPixels(&bm, legacyColorSpace)) {
        return SkEncodeBitmap(bm, type, quality);
    }
    return nullptr;
}
Example #15
0
void SkBaseDevice::drawImageRect(const SkImage* image, const SkRect* src,
                                 const SkRect& dst, const SkPaint& paint,
                                 SkCanvas::SrcRectConstraint constraint) {
    SkBitmap bm;
    if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
        this->drawBitmapRect(bm, src, dst, paint, constraint);
    }
}
Example #16
0
bool SkBitmapProvider::asBitmap(SkBitmap* bm) const {
    if (fImage) {
        return as_IB(fImage)->getROPixels(bm, SkImage::kAllow_CachingHint);
    } else {
        *bm = fBitmap;
        return true;
    }
}
Example #17
0
    bool getBitmapDeprecated(SkBitmap* result) const override {
#if SK_SUPPORT_GPU
        if (GrTexture* texture = as_IB(fImage.get())->peekTexture()) {
            const SkImageInfo info = GrMakeInfoFromTexture(texture,
                                                           fImage->width(), fImage->height(),
                                                           fImage->isOpaque());
            if (!result->setInfo(info)) {
                return false;
            }

            result->setPixelRef(new SkGrPixelRef(info, texture))->unref();
            return true;
        }
#endif

        return as_IB(fImage.get())->asBitmapForImageFilters(result);
    }
Example #18
0
void SkBaseDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
                             const SkPaint& paint) {
    // Default impl : turns everything into raster bitmap
    SkBitmap bm;
    if (as_IB(image)->getROPixels(&bm)) {
        this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
    }
}
Example #19
0
bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
                           int srcX, int srcY) const {
    SkReadPixelsRec rec(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
    if (!rec.trim(this->width(), this->height())) {
        return false;
    }
    return as_IB(this)->onReadPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY);
}
Example #20
0
const GrFragmentProcessor* SkImageShader::asFragmentProcessor(GrContext* context,
        const SkMatrix& viewM,
        const SkMatrix* localMatrix,
        SkFilterQuality filterQuality,
        GrProcessorDataManager* mgr) const {
    SkMatrix matrix;
    matrix.setIDiv(fImage->width(), fImage->height());

    SkMatrix lmInverse;
    if (!this->getLocalMatrix().invert(&lmInverse)) {
        return nullptr;
    }
    if (localMatrix) {
        SkMatrix inv;
        if (!localMatrix->invert(&inv)) {
            return nullptr;
        }
        lmInverse.postConcat(inv);
    }
    matrix.preConcat(lmInverse);

    SkShader::TileMode tm[] = { fTileModeX, fTileModeY };

    // Must set wrap and filter on the sampler before requesting a texture. In two places below
    // we check the matrix scale factors to determine how to interpret the filter quality setting.
    // This completely ignores the complexity of the drawVertices case where explicit local coords
    // are provided by the caller.
    bool doBicubic;
    GrTextureParams::FilterMode textureFilterMode =
        GrSkFilterQualityToGrFilterMode(filterQuality, viewM, this->getLocalMatrix(), &doBicubic);
    GrTextureParams params(tm, textureFilterMode);

    SkImageUsageType usageType;
    if (kClamp_TileMode == fTileModeX && kClamp_TileMode == fTileModeY) {
        usageType = kUntiled_SkImageUsageType;
    } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
        usageType = kTiled_Unfiltered_SkImageUsageType;
    } else {
        usageType = kTiled_Filtered_SkImageUsageType;
    }

    SkAutoTUnref<GrTexture> texture(as_IB(fImage)->asTextureRef(context, usageType));
    if (!texture) {
        return nullptr;
    }

    SkAutoTUnref<GrFragmentProcessor> inner;
    if (doBicubic) {
        inner.reset(GrBicubicEffect::Create(mgr, texture, matrix, tm));
    } else {
        inner.reset(GrSimpleTextureEffect::Create(mgr, texture, matrix, params));
    }

    if (GrPixelConfigIsAlphaOnly(texture->config())) {
        return SkRef(inner.get());
    }
    return GrFragmentProcessor::MulOuputByInputAlpha(inner);
}
Example #21
0
void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
                                 const SkRect& dst, const SkPaint& paint,
                                 SkCanvas::SrcRectConstraint constraint) {
    // Default impl : turns everything into raster bitmap
    SkBitmap bm;
    if (as_IB(image)->getROPixels(&bm)) {
        this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
    }
}
Example #22
0
    sk_sp<SkSurface> onMakeTightSurface(const SkImageInfo& info) const override {
#if SK_SUPPORT_GPU
        GrTexture* texture = as_IB(fImage.get())->peekTexture();
        if (texture) {
            return SkSurface::MakeRenderTarget(texture->getContext(), SkBudgeted::kYes, info);
        }
#endif
        return SkSurface::MakeRaster(info, nullptr);
    }
Example #23
0
SkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) {
    const int sampleCount = fDevice->accessRenderTarget()->numSamples();
    SkImage* image = SkNewImageFromBitmapTexture(fDevice->accessBitmap(false), sampleCount,
                                                 budgeted);
    if (image) {
        as_IB(image)->initWithProps(this->props());
    }
    return image;
}
Example #24
0
sk_sp<SkImage> SkImage::makeTextureImage(GrContext *context) const {
    if (!context) {
        return nullptr;
    }
    if (GrTexture* peek = as_IB(this)->peekTexture()) {
        return peek->getContext() == context ? sk_ref_sp(const_cast<SkImage*>(this)) : nullptr;
    }

    if (SkImageCacherator* cacher = as_IB(this)->peekCacherator()) {
        GrImageTextureMaker maker(context, cacher, this, kDisallow_CachingHint);
        return create_image_from_maker(&maker, this->alphaType(), this->uniqueID());
    }

    if (const SkBitmap* bmp = as_IB(this)->onPeekBitmap()) {
        GrBitmapTextureMaker maker(context, *bmp);
        return create_image_from_maker(&maker, this->alphaType(), this->uniqueID());
    }
    return nullptr;
}
Example #25
0
void SkImage::preroll(GrContext* ctx) const {
    // For now, and to maintain parity w/ previous pixelref behavior, we just force the image
    // to produce a cached raster-bitmap form, so that drawing to a raster canvas should be fast.
    //
    SkBitmap bm;
    if (as_IB(this)->getROPixels(&bm)) {
        bm.lockPixels();
        bm.unlockPixels();
    }
}
Example #26
0
sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(const SkIRect& subset,
        sk_sp<SkImage> image,
        const SkSurfaceProps* props) {
    SkASSERT(rect_fits(subset, image->width(), image->height()));

#if SK_SUPPORT_GPU
    if (GrTexture* texture = as_IB(image)->peekTexture()) {
        return MakeFromGpu(subset, image->uniqueID(), sk_ref_sp(texture),
                           sk_ref_sp(as_IB(image)->onImageInfo().colorSpace()), props);
    } else
#endif
    {
        SkBitmap bm;
        if (as_IB(image)->getROPixels(&bm)) {
            return MakeFromRaster(subset, bm, props);
        }
    }
    return nullptr;
}
Example #27
0
const void* SkImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const {
    SkImageInfo infoStorage;
    size_t rowBytesStorage;
    if (NULL == info) {
        info = &infoStorage;
    }
    if (NULL == rowBytes) {
        rowBytes = &rowBytesStorage;
    }
    return as_IB(this)->onPeekPixels(info, rowBytes);
}
Example #28
0
bool SkImage::readYUV8Planes(const SkISize sizes[3], void* const planes[3],
                             const size_t rowBytes[3], SkYUVColorSpace colorSpace) const {
#if SK_SUPPORT_GPU
    if (GrTexture* texture = as_IB(this)->peekTexture()) {
        if (GrTextureToYUVPlanes(texture, sizes, planes, rowBytes, colorSpace)) {
            return true;
        }
    }
#endif
    return SkRGBAToYUV(this, sizes, planes, rowBytes, colorSpace);
}
Example #29
0
    sk_sp<SkSpecialSurface> onMakeSurface(const SkImageInfo& info) const override {
#if SK_SUPPORT_GPU
        GrTexture* texture = as_IB(fImage.get())->peekTexture();
        if (texture) {
            GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info, *texture->getContext()->caps());
            desc.fFlags = kRenderTarget_GrSurfaceFlag;

            return SkSpecialSurface::MakeRenderTarget(texture->getContext(), desc);
        }
#endif
        return SkSpecialSurface::MakeRaster(info, nullptr);
    }
Example #30
0
sk_sp<SkImage> SkImage::makeTextureImage(GrContext *context) const {
    if (!context) {
        return nullptr;
    }
    if (GrTexture* peek = as_IB(this)->peekTexture()) {
        return peek->getContext() == context ? sk_ref_sp(const_cast<SkImage*>(this)) : nullptr;
    }
    // No way to check whether a image is premul or not?
    SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType;

    if (SkImageCacherator* cacher = as_IB(this)->peekCacherator()) {
        GrImageTextureMaker maker(context, cacher, this, kDisallow_CachingHint);
        return create_image_from_maker(&maker, at, this->uniqueID());
    }
    SkBitmap bmp;
    if (!this->asLegacyBitmap(&bmp, kRO_LegacyBitmapMode)) {
        return nullptr;
    }
    GrBitmapTextureMaker maker(context, bmp);
    return create_image_from_maker(&maker, at, this->uniqueID());
}