| Index: src/effects/SkLightingImageFilter.cpp
|
| diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
|
| index e60e7ed370b4c4c4c009eb7f1c412e2a0187104a..b37fc28b2a6961554e7054a385ee002901c5ac33 100644
|
| --- a/src/effects/SkLightingImageFilter.cpp
|
| +++ b/src/effects/SkLightingImageFilter.cpp
|
| @@ -8,9 +8,9 @@
|
| #include "SkLightingImageFilter.h"
|
| #include "SkBitmap.h"
|
| #include "SkColorPriv.h"
|
| -#include "SkDevice.h"
|
| #include "SkPoint3.h"
|
| #include "SkReadBuffer.h"
|
| +#include "SkSpecialImage.h"
|
| #include "SkTypes.h"
|
| #include "SkWriteBuffer.h"
|
|
|
| @@ -355,9 +355,10 @@ protected:
|
| }
|
|
|
| #if SK_SUPPORT_GPU
|
| - bool canFilterImageGPU() const override { return true; }
|
| - bool filterImageGPUDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
| - SkBitmap* result, SkIPoint* offset) const override;
|
| + sk_sp<SkSpecialImage> filterImageGPU(SkSpecialImage* source,
|
| + SkSpecialImage* input,
|
| + const SkIRect& bounds,
|
| + const SkMatrix& matrix) const;
|
| virtual GrFragmentProcessor* getFragmentProcessor(GrTexture*,
|
| const SkMatrix&,
|
| const SkIRect* srcBounds,
|
| @@ -395,47 +396,40 @@ void SkLightingImageFilterInternal::drawRect(GrDrawContext* drawContext,
|
| drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
|
| }
|
|
|
| -bool SkLightingImageFilterInternal::filterImageGPUDeprecated(Proxy* proxy,
|
| - const SkBitmap& src,
|
| - const Context& ctx,
|
| - SkBitmap* result,
|
| - SkIPoint* offset) const {
|
| - SkBitmap input = src;
|
| - SkIPoint srcOffset = SkIPoint::Make(0, 0);
|
| - if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &input, &srcOffset)) {
|
| - return false;
|
| - }
|
| - SkIRect srcBounds = input.bounds();
|
| - srcBounds.offset(srcOffset);
|
| - SkIRect bounds;
|
| - if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
|
| - return false;
|
| - }
|
| - SkRect dstRect = SkRect::MakeWH(SkIntToScalar(bounds.width()),
|
| - SkIntToScalar(bounds.height()));
|
| - GrTexture* srcTexture = input.getTexture();
|
| - GrContext* context = srcTexture->getContext();
|
| +sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(SkSpecialImage* source,
|
| + SkSpecialImage* input,
|
| + const SkIRect& offsetBounds,
|
| + const SkMatrix& matrix) const {
|
| + SkASSERT(source->isTextureBacked());
|
| +
|
| + GrContext* context = source->getContext();
|
| +
|
| + sk_sp<GrTexture> inputTexture(input->asTextureRef(context));
|
| + SkASSERT(inputTexture);
|
|
|
| GrSurfaceDesc desc;
|
| desc.fFlags = kRenderTarget_GrSurfaceFlag,
|
| - desc.fWidth = bounds.width();
|
| - desc.fHeight = bounds.height();
|
| + desc.fWidth = offsetBounds.width();
|
| + desc.fHeight = offsetBounds.height();
|
| desc.fConfig = kRGBA_8888_GrPixelConfig;
|
|
|
| - SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc));
|
| + sk_sp<GrTexture> dst(context->textureProvider()->createApproxTexture(desc));
|
| if (!dst) {
|
| - return false;
|
| + return nullptr;
|
| + }
|
| +
|
| + sk_sp<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
|
| + if (!drawContext) {
|
| + return nullptr;
|
| }
|
|
|
| + SkRect dstRect = SkRect::MakeWH(SkIntToScalar(offsetBounds.width()),
|
| + SkIntToScalar(offsetBounds.height()));
|
| +
|
| // setup new clip
|
| GrClip clip(dstRect);
|
|
|
| - offset->fX = bounds.left();
|
| - offset->fY = bounds.top();
|
| - SkMatrix matrix(ctx.ctm());
|
| - matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
|
| - bounds.offset(-srcOffset);
|
| - srcBounds.offset(-srcOffset);
|
| + const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height());
|
| SkRect topLeft = SkRect::MakeXYWH(0, 0, 1, 1);
|
| SkRect top = SkRect::MakeXYWH(1, 0, dstRect.width() - 2, 1);
|
| SkRect topRight = SkRect::MakeXYWH(dstRect.width() - 1, 0, 1, 1);
|
| @@ -446,32 +440,30 @@ bool SkLightingImageFilterInternal::filterImageGPUDeprecated(Proxy* proxy,
|
| SkRect bottom = SkRect::MakeXYWH(1, dstRect.height() - 1, dstRect.width() - 2, 1);
|
| SkRect bottomRight = SkRect::MakeXYWH(dstRect.width() - 1, dstRect.height() - 1, 1, 1);
|
|
|
| - SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
|
| - if (!drawContext) {
|
| - return false;
|
| - }
|
| -
|
| - const SkIRect* pSrcBounds = srcBounds.contains(bounds) ? nullptr : &srcBounds;
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, topLeft, kTopLeft_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, top, kTop_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, topRight, kTopRight_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, left, kLeft_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, interior, kInterior_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, right, kRight_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, bottomLeft, kBottomLeft_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, bottom, kBottom_BoundaryMode,
|
| - pSrcBounds, bounds);
|
| - this->drawRect(drawContext, srcTexture, matrix, clip, bottomRight,
|
| - kBottomRight_BoundaryMode, pSrcBounds, bounds);
|
| - GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result);
|
| - return true;
|
| + const SkIRect* pSrcBounds = inputBounds.contains(offsetBounds) ? nullptr : &inputBounds;
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, topLeft,
|
| + kTopLeft_BoundaryMode, pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, top, kTop_BoundaryMode,
|
| + pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, topRight,
|
| + kTopRight_BoundaryMode, pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, left, kLeft_BoundaryMode,
|
| + pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, interior,
|
| + kInterior_BoundaryMode, pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, right, kRight_BoundaryMode,
|
| + pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, bottomLeft,
|
| + kBottomLeft_BoundaryMode, pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, bottom,
|
| + kBottom_BoundaryMode, pSrcBounds, offsetBounds);
|
| + this->drawRect(drawContext.get(), inputTexture.get(), matrix, clip, bottomRight,
|
| + kBottomRight_BoundaryMode, pSrcBounds, offsetBounds);
|
| +
|
| + return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
|
| + SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height()),
|
| + kNeedNewImageUniqueID_SpecialImage,
|
| + dst.get());
|
| }
|
| #endif
|
|
|
| @@ -492,8 +484,10 @@ protected:
|
| SkScalar kd,
|
| sk_sp<SkImageFilter> input, const CropRect* cropRect);
|
| void flatten(SkWriteBuffer& buffer) const override;
|
| - bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
| - SkBitmap* result, SkIPoint* offset) const override;
|
| +
|
| + sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
| + SkIPoint* offset) const override;
|
| +
|
| #if SK_SUPPORT_GPU
|
| GrFragmentProcessor* getFragmentProcessor(GrTexture*, const SkMatrix&, const SkIRect* bounds,
|
| BoundaryMode) const override;
|
| @@ -501,8 +495,9 @@ protected:
|
|
|
| private:
|
| friend class SkLightingImageFilter;
|
| - typedef SkLightingImageFilterInternal INHERITED;
|
| SkScalar fKD;
|
| +
|
| + typedef SkLightingImageFilterInternal INHERITED;
|
| };
|
|
|
| class SkSpecularLightingImageFilter : public SkLightingImageFilterInternal {
|
| @@ -524,8 +519,10 @@ protected:
|
| SkScalar shininess,
|
| sk_sp<SkImageFilter> input, const CropRect*);
|
| void flatten(SkWriteBuffer& buffer) const override;
|
| - bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
| - SkBitmap* result, SkIPoint* offset) const override;
|
| +
|
| + sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
| + SkIPoint* offset) const override;
|
| +
|
| #if SK_SUPPORT_GPU
|
| GrFragmentProcessor* getFragmentProcessor(GrTexture*, const SkMatrix&, const SkIRect* bounds,
|
| BoundaryMode) const override;
|
| @@ -1239,79 +1236,99 @@ void SkDiffuseLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
|
| buffer.writeScalar(fKD);
|
| }
|
|
|
| -bool SkDiffuseLightingImageFilter::onFilterImageDeprecated(Proxy* proxy,
|
| - const SkBitmap& source,
|
| - const Context& ctx,
|
| - SkBitmap* dst,
|
| - SkIPoint* offset) const {
|
| - SkBitmap src = source;
|
| - SkIPoint srcOffset = SkIPoint::Make(0, 0);
|
| - if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
|
| - return false;
|
| +sk_sp<SkSpecialImage> SkDiffuseLightingImageFilter::onFilterImage(SkSpecialImage* source,
|
| + const Context& ctx,
|
| + SkIPoint* offset) const {
|
| + SkIPoint inputOffset = SkIPoint::Make(0, 0);
|
| + sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
|
| + if (!input) {
|
| + return nullptr;
|
| }
|
|
|
| - if (src.colorType() != kN32_SkColorType) {
|
| - return false;
|
| - }
|
| - SkIRect srcBounds = src.bounds();
|
| - srcBounds.offset(srcOffset);
|
| + const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
|
| + input->width(), input->height());
|
| SkIRect bounds;
|
| - if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
|
| - return false;
|
| + if (!this->applyCropRect(ctx, inputBounds, &bounds)) {
|
| + return nullptr;
|
| }
|
|
|
| + offset->fX = bounds.left();
|
| + offset->fY = bounds.top();
|
| + bounds.offset(-inputOffset);
|
| +
|
| +#if SK_SUPPORT_GPU
|
| + if (source->isTextureBacked()) {
|
| + SkMatrix matrix(ctx.ctm());
|
| + matrix.postTranslate(SkIntToScalar(-offset->fX), SkIntToScalar(-offset->fY));
|
| +
|
| + return this->filterImageGPU(source, input.get(), bounds, matrix);
|
| + }
|
| +#endif
|
| +
|
| if (bounds.width() < 2 || bounds.height() < 2) {
|
| - return false;
|
| + return nullptr;
|
| + }
|
| +
|
| + SkBitmap inputBM;
|
| +
|
| + if (!input->getROPixels(&inputBM)) {
|
| + return nullptr;
|
| }
|
|
|
| - SkAutoLockPixels alp(src);
|
| - if (!src.getPixels()) {
|
| - return false;
|
| + if (inputBM.colorType() != kN32_SkColorType) {
|
| + return nullptr;
|
| }
|
|
|
| - SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
|
| - if (!device) {
|
| - return false;
|
| + SkAutoLockPixels alp(inputBM);
|
| + if (!inputBM.getPixels()) {
|
| + return nullptr;
|
| + }
|
| +
|
| + const SkImageInfo info = SkImageInfo::MakeN32Premul(bounds.width(), bounds.height());
|
| +
|
| + SkBitmap dst;
|
| + if (!dst.tryAllocPixels(info)) {
|
| + return nullptr;
|
| }
|
| - *dst = device->accessBitmap(false);
|
| - SkAutoLockPixels alp_dst(*dst);
|
| +
|
| + SkAutoLockPixels dstLock(dst);
|
|
|
| SkMatrix matrix(ctx.ctm());
|
| - matrix.postTranslate(SkIntToScalar(-srcOffset.x()), SkIntToScalar(-srcOffset.y()));
|
| - SkAutoTUnref<SkImageFilterLight> transformedLight(light()->transform(matrix));
|
| + matrix.postTranslate(SkIntToScalar(-inputOffset.x()), SkIntToScalar(-inputOffset.y()));
|
| +
|
| + sk_sp<SkImageFilterLight> transformedLight(light()->transform(matrix));
|
|
|
| DiffuseLightingType lightingType(fKD);
|
| - offset->fX = bounds.left();
|
| - offset->fY = bounds.top();
|
| - bounds.offset(-srcOffset);
|
| switch (transformedLight->type()) {
|
| case SkImageFilterLight::kDistant_LightType:
|
| lightBitmap<DiffuseLightingType, SkDistantLight>(lightingType,
|
| - transformedLight,
|
| - src,
|
| - dst,
|
| + transformedLight.get(),
|
| + inputBM,
|
| + &dst,
|
| surfaceScale(),
|
| bounds);
|
| break;
|
| case SkImageFilterLight::kPoint_LightType:
|
| lightBitmap<DiffuseLightingType, SkPointLight>(lightingType,
|
| - transformedLight,
|
| - src,
|
| - dst,
|
| + transformedLight.get(),
|
| + inputBM,
|
| + &dst,
|
| surfaceScale(),
|
| bounds);
|
| break;
|
| case SkImageFilterLight::kSpot_LightType:
|
| lightBitmap<DiffuseLightingType, SkSpotLight>(lightingType,
|
| - transformedLight,
|
| - src,
|
| - dst,
|
| + transformedLight.get(),
|
| + inputBM,
|
| + &dst,
|
| surfaceScale(),
|
| bounds);
|
| break;
|
| }
|
|
|
| - return true;
|
| + return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
|
| + SkIRect::MakeWH(bounds.width(), bounds.height()),
|
| + dst);
|
| }
|
|
|
| #ifndef SK_IGNORE_TO_STRING
|
| @@ -1385,78 +1402,100 @@ void SkSpecularLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
|
| buffer.writeScalar(fShininess);
|
| }
|
|
|
| -bool SkSpecularLightingImageFilter::onFilterImageDeprecated(Proxy* proxy,
|
| - const SkBitmap& source,
|
| - const Context& ctx,
|
| - SkBitmap* dst,
|
| - SkIPoint* offset) const {
|
| - SkBitmap src = source;
|
| - SkIPoint srcOffset = SkIPoint::Make(0, 0);
|
| - if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
|
| - return false;
|
| +sk_sp<SkSpecialImage> SkSpecularLightingImageFilter::onFilterImage(SkSpecialImage* source,
|
| + const Context& ctx,
|
| + SkIPoint* offset) const {
|
| + SkIPoint inputOffset = SkIPoint::Make(0, 0);
|
| + sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
|
| + if (!input) {
|
| + return nullptr;
|
| }
|
|
|
| - if (src.colorType() != kN32_SkColorType) {
|
| - return false;
|
| + const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
|
| + input->width(), input->height());
|
| + SkIRect bounds;
|
| + if (!this->applyCropRect(ctx, inputBounds, &bounds)) {
|
| + return nullptr;
|
| }
|
|
|
| - SkIRect srcBounds = src.bounds();
|
| - srcBounds.offset(srcOffset);
|
| - SkIRect bounds;
|
| - if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
|
| - return false;
|
| + offset->fX = bounds.left();
|
| + offset->fY = bounds.top();
|
| + bounds.offset(-inputOffset);
|
| +
|
| +#if SK_SUPPORT_GPU
|
| + if (source->isTextureBacked()) {
|
| + SkMatrix matrix(ctx.ctm());
|
| + matrix.postTranslate(SkIntToScalar(-offset->fX), SkIntToScalar(-offset->fY));
|
| +
|
| + return this->filterImageGPU(source, input.get(), bounds, matrix);
|
| }
|
| +#endif
|
|
|
| if (bounds.width() < 2 || bounds.height() < 2) {
|
| - return false;
|
| + return nullptr;
|
| + }
|
| +
|
| + SkBitmap inputBM;
|
| +
|
| + if (!input->getROPixels(&inputBM)) {
|
| + return nullptr;
|
| }
|
|
|
| - SkAutoLockPixels alp(src);
|
| - if (!src.getPixels()) {
|
| - return false;
|
| + if (inputBM.colorType() != kN32_SkColorType) {
|
| + return nullptr;
|
| }
|
|
|
| - SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
|
| - if (!device) {
|
| - return false;
|
| + SkAutoLockPixels alp(inputBM);
|
| + if (!inputBM.getPixels()) {
|
| + return nullptr;
|
| }
|
| - *dst = device->accessBitmap(false);
|
| - SkAutoLockPixels alp_dst(*dst);
|
| +
|
| + const SkImageInfo info = SkImageInfo::MakeN32Premul(bounds.width(), bounds.height());
|
| +
|
| + SkBitmap dst;
|
| + if (!dst.tryAllocPixels(info)) {
|
| + return nullptr;
|
| + }
|
| +
|
| + SkAutoLockPixels dstLock(dst);
|
|
|
| SpecularLightingType lightingType(fKS, fShininess);
|
| - offset->fX = bounds.left();
|
| - offset->fY = bounds.top();
|
| +
|
| SkMatrix matrix(ctx.ctm());
|
| - matrix.postTranslate(SkIntToScalar(-srcOffset.x()), SkIntToScalar(-srcOffset.y()));
|
| - SkAutoTUnref<SkImageFilterLight> transformedLight(light()->transform(matrix));
|
| - bounds.offset(-srcOffset);
|
| + matrix.postTranslate(SkIntToScalar(-inputOffset.x()), SkIntToScalar(-inputOffset.y()));
|
| +
|
| + sk_sp<SkImageFilterLight> transformedLight(light()->transform(matrix));
|
| +
|
| switch (transformedLight->type()) {
|
| case SkImageFilterLight::kDistant_LightType:
|
| lightBitmap<SpecularLightingType, SkDistantLight>(lightingType,
|
| - transformedLight,
|
| - src,
|
| - dst,
|
| + transformedLight.get(),
|
| + inputBM,
|
| + &dst,
|
| surfaceScale(),
|
| bounds);
|
| break;
|
| case SkImageFilterLight::kPoint_LightType:
|
| lightBitmap<SpecularLightingType, SkPointLight>(lightingType,
|
| - transformedLight,
|
| - src,
|
| - dst,
|
| + transformedLight.get(),
|
| + inputBM,
|
| + &dst,
|
| surfaceScale(),
|
| bounds);
|
| break;
|
| case SkImageFilterLight::kSpot_LightType:
|
| lightBitmap<SpecularLightingType, SkSpotLight>(lightingType,
|
| - transformedLight,
|
| - src,
|
| - dst,
|
| + transformedLight.get(),
|
| + inputBM,
|
| + &dst,
|
| surfaceScale(),
|
| bounds);
|
| break;
|
| }
|
| - return true;
|
| +
|
| + return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
|
| + SkIRect::MakeWH(bounds.width(), bounds.height()),
|
| + dst);
|
| }
|
|
|
| #ifndef SK_IGNORE_TO_STRING
|
|
|