stop using bitmapcontroller
This moves all shaders to a common utility for resolve the mip-level request. Change-Id: I26709d5a55adf97cb4c61473527a9bbbdc689aa5 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/339897 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
f5e1bf9f01
commit
8c1ad7e8d3
@ -11,7 +11,6 @@
|
|||||||
#include "src/core/SkArenaAlloc.h"
|
#include "src/core/SkArenaAlloc.h"
|
||||||
#include "src/core/SkBitmapCache.h"
|
#include "src/core/SkBitmapCache.h"
|
||||||
#include "src/core/SkBitmapController.h"
|
#include "src/core/SkBitmapController.h"
|
||||||
#include "src/core/SkMatrixPriv.h"
|
|
||||||
#include "src/core/SkMipmap.h"
|
#include "src/core/SkMipmap.h"
|
||||||
#include "src/image/SkImage_Base.h"
|
#include "src/image/SkImage_Base.h"
|
||||||
|
|
||||||
@ -27,86 +26,6 @@ static sk_sp<const SkMipmap> try_load_mips(const SkImage_Base* image) {
|
|||||||
return mips;
|
return mips;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
SkBitmapController::State* SkBitmapController::RequestBitmap(const SkImage_Base* image,
|
|
||||||
const SkMatrix& inv,
|
|
||||||
const SkSamplingOptions& sampling,
|
|
||||||
SkArenaAlloc* alloc) {
|
|
||||||
auto* state = alloc->make<SkBitmapController::State>(image, inv, sampling);
|
|
||||||
|
|
||||||
return state->pixmap().addr() ? state : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Modulo internal errors, this should always succeed *if* the matrix is downscaling
|
|
||||||
* (in this case, we have the inverse, so it succeeds if fInvMatrix is upscaling)
|
|
||||||
*/
|
|
||||||
bool SkBitmapController::State::extractMipLevel(const SkImage_Base* image) {
|
|
||||||
SkASSERT(!fSampling.useCubic);
|
|
||||||
if (fSampling.mipmap != SkMipmapMode::kNearest) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will extract the right level here, so mark fSampling to know that has already happened.
|
|
||||||
fSampling = SkSamplingOptions(fSampling.filter, SkMipmapMode::kNone);
|
|
||||||
|
|
||||||
SkSize invScaleSize;
|
|
||||||
if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invScaleSize.width() > SK_Scalar1 || invScaleSize.height() > SK_Scalar1) {
|
|
||||||
fCurrMip = try_load_mips(image);
|
|
||||||
if (!fCurrMip) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// diagnostic for a crasher...
|
|
||||||
SkASSERT_RELEASE(fCurrMip->data());
|
|
||||||
|
|
||||||
const SkSize scale = SkSize::Make(SkScalarInvert(invScaleSize.width()),
|
|
||||||
SkScalarInvert(invScaleSize.height()));
|
|
||||||
SkMipmap::Level level;
|
|
||||||
if (fCurrMip->extractLevel(scale, &level)) {
|
|
||||||
const SkSize& invScaleFixup = level.fScale;
|
|
||||||
fInvMatrix.postScale(invScaleFixup.width(), invScaleFixup.height());
|
|
||||||
|
|
||||||
// todo: if we could wrap the fCurrMip in a pixelref, then we could just install
|
|
||||||
// that here, and not need to explicitly track it ourselves.
|
|
||||||
return fResultBitmap.installPixels(level.fPixmap);
|
|
||||||
} else {
|
|
||||||
// failed to extract, so release the mipmap
|
|
||||||
fCurrMip.reset(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkBitmapController::State::State(const SkImage_Base* image,
|
|
||||||
const SkMatrix& inv,
|
|
||||||
const SkSamplingOptions& sampling)
|
|
||||||
: fInvMatrix(inv)
|
|
||||||
, fSampling(sampling)
|
|
||||||
{
|
|
||||||
if (fSampling.useCubic &&
|
|
||||||
SkMatrixPriv::AdjustHighQualityFilterLevel(fInvMatrix, true) != kHigh_SkFilterQuality)
|
|
||||||
{
|
|
||||||
fSampling = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fSampling.useCubic && this->extractMipLevel(image)) {
|
|
||||||
SkASSERT(fResultBitmap.getPixels());
|
|
||||||
} else {
|
|
||||||
(void)image->getROPixels(nullptr, &fResultBitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fResultBitmap.getPixels() may be null, but our caller knows to check fPixmap.addr()
|
|
||||||
// and will destroy us if it is nullptr.
|
|
||||||
fPixmap.reset(fResultBitmap.info(), fResultBitmap.getPixels(), fResultBitmap.rowBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
SkMipmapAccessor::SkMipmapAccessor(const SkImage_Base* image, const SkMatrix& inv,
|
SkMipmapAccessor::SkMipmapAccessor(const SkImage_Base* image, const SkMatrix& inv,
|
||||||
SkMipmapMode requestedMode) {
|
SkMipmapMode requestedMode) {
|
||||||
fResolvedMode = requestedMode;
|
fResolvedMode = requestedMode;
|
||||||
@ -134,6 +53,11 @@ SkMipmapAccessor::SkMipmapAccessor(const SkImage_Base* image, const SkMatrix& in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto post_scale = [image, inv](const SkPixmap& pm) {
|
||||||
|
return SkMatrix::Scale(SkIntToScalar(pm.width()) / image->width(),
|
||||||
|
SkIntToScalar(pm.height()) / image->height()) * inv;
|
||||||
|
};
|
||||||
|
|
||||||
int levelNum = sk_float_floor2int(level);
|
int levelNum = sk_float_floor2int(level);
|
||||||
float lowerWeight = level - levelNum; // fract(level)
|
float lowerWeight = level - levelNum; // fract(level)
|
||||||
SkASSERT(levelNum >= 0);
|
SkASSERT(levelNum >= 0);
|
||||||
@ -164,10 +88,12 @@ SkMipmapAccessor::SkMipmapAccessor(const SkImage_Base* image, const SkMatrix& in
|
|||||||
if (fCurrMip->getLevel(levelNum, &levelRec)) {
|
if (fCurrMip->getLevel(levelNum, &levelRec)) {
|
||||||
fLower = levelRec.fPixmap;
|
fLower = levelRec.fPixmap;
|
||||||
fLowerWeight = lowerWeight;
|
fLowerWeight = lowerWeight;
|
||||||
|
fLowerInv = post_scale(fLower);
|
||||||
} else {
|
} else {
|
||||||
fResolvedMode = SkMipmapMode::kNearest;
|
fResolvedMode = SkMipmapMode::kNearest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fUpperInv = post_scale(fUpper);
|
||||||
}
|
}
|
||||||
|
@ -9,62 +9,35 @@
|
|||||||
#define SkBitmapController_DEFINED
|
#define SkBitmapController_DEFINED
|
||||||
|
|
||||||
#include "include/core/SkBitmap.h"
|
#include "include/core/SkBitmap.h"
|
||||||
#include "include/core/SkFilterQuality.h"
|
|
||||||
#include "include/core/SkImage.h"
|
#include "include/core/SkImage.h"
|
||||||
#include "include/core/SkMatrix.h"
|
#include "include/core/SkMatrix.h"
|
||||||
#include "src/core/SkBitmapCache.h"
|
|
||||||
#include "src/core/SkMipmap.h"
|
#include "src/core/SkMipmap.h"
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
class SkImage_Base;
|
class SkImage_Base;
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles request to scale, filter, and lock a bitmap to be rasterized.
|
|
||||||
*/
|
|
||||||
class SkBitmapController : ::SkNoncopyable {
|
|
||||||
public:
|
|
||||||
class State : ::SkNoncopyable {
|
|
||||||
public:
|
|
||||||
State(const SkImage_Base*, const SkMatrix& inv, const SkSamplingOptions&);
|
|
||||||
|
|
||||||
const SkPixmap& pixmap() const { return fPixmap; }
|
|
||||||
const SkMatrix& invMatrix() const { return fInvMatrix; }
|
|
||||||
const SkSamplingOptions& sampling() const { return fSampling; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool extractMipLevel(const SkImage_Base*);
|
|
||||||
|
|
||||||
SkPixmap fPixmap;
|
|
||||||
SkMatrix fInvMatrix;
|
|
||||||
SkSamplingOptions fSampling;
|
|
||||||
|
|
||||||
// Pixmap storage.
|
|
||||||
SkBitmap fResultBitmap;
|
|
||||||
sk_sp<const SkMipmap> fCurrMip;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static State* RequestBitmap(const SkImage_Base*, const SkMatrix& inverse,
|
|
||||||
const SkSamplingOptions&, SkArenaAlloc*);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SkBitmapController() = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SkMipmapAccessor : ::SkNoncopyable {
|
class SkMipmapAccessor : ::SkNoncopyable {
|
||||||
public:
|
public:
|
||||||
SkMipmapAccessor(const SkImage_Base*, const SkMatrix& inv, SkMipmapMode requestedMode);
|
SkMipmapAccessor(const SkImage_Base*, const SkMatrix& inv, SkMipmapMode requestedMode);
|
||||||
|
|
||||||
const SkPixmap& level() const { return fUpper; }
|
std::pair<SkPixmap, SkMatrix> level() const { return std::make_pair(fUpper, fUpperInv); }
|
||||||
// only valid if mode() == kLinear
|
|
||||||
const SkPixmap& lowerLevel() const { return fLower; }
|
std::pair<SkPixmap, SkMatrix> lowerLevel() const {
|
||||||
// 0....1. Will be 1.0 if there is no lowerLevel
|
SkASSERT(this->mode() == SkMipmapMode::kLinear);
|
||||||
float lowerWeight() const { return fLowerWeight; }
|
return std::make_pair(fLower, fLowerInv);
|
||||||
SkMipmapMode mode() const { return fResolvedMode; }
|
}
|
||||||
|
|
||||||
|
// 0....1. Will be 0 if there is no lowerLevel
|
||||||
|
float lowerWeight() const { return fLowerWeight; }
|
||||||
|
|
||||||
|
SkMipmapMode mode() const { return fResolvedMode; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkPixmap fUpper,
|
SkPixmap fUpper,
|
||||||
fLower; // only valid for mip_linear
|
fLower; // only valid for mip_linear
|
||||||
float fLowerWeight; // lower * weight + upper * (1 - weight)
|
float fLowerWeight; // lower * weight + upper * (1 - weight)
|
||||||
|
SkMatrix fUpperInv,
|
||||||
|
fLowerInv;
|
||||||
SkMipmapMode fResolvedMode;
|
SkMipmapMode fResolvedMode;
|
||||||
|
|
||||||
// these manage lifetime for the buffers
|
// these manage lifetime for the buffers
|
||||||
|
@ -143,10 +143,8 @@ SkBitmapProcState::SkBitmapProcState(const SkImage_Base* image, SkTileMode tmx,
|
|||||||
: fImage(image)
|
: fImage(image)
|
||||||
, fTileModeX(tmx)
|
, fTileModeX(tmx)
|
||||||
, fTileModeY(tmy)
|
, fTileModeY(tmy)
|
||||||
, fBMState(nullptr)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// true iff the matrix has a scale and no more than an optional translate.
|
// true iff the matrix has a scale and no more than an optional translate.
|
||||||
static bool matrix_only_scale_translate(const SkMatrix& m) {
|
static bool matrix_only_scale_translate(const SkMatrix& m) {
|
||||||
return (m.getType() & ~SkMatrix::kTranslate_Mask) == SkMatrix::kScale_Mask;
|
return (m.getType() & ~SkMatrix::kTranslate_Mask) == SkMatrix::kScale_Mask;
|
||||||
@ -187,23 +185,22 @@ bool SkBitmapProcState::init(const SkMatrix& inv, SkColor paintColor,
|
|||||||
const SkSamplingOptions& sampling) {
|
const SkSamplingOptions& sampling) {
|
||||||
SkASSERT(!inv.hasPerspective());
|
SkASSERT(!inv.hasPerspective());
|
||||||
SkASSERT(SkOpts::S32_alpha_D32_filter_DXDY || inv.isScaleTranslate());
|
SkASSERT(SkOpts::S32_alpha_D32_filter_DXDY || inv.isScaleTranslate());
|
||||||
|
SkASSERT(!sampling.useCubic);
|
||||||
|
SkASSERT(sampling.mipmap != SkMipmapMode::kLinear);
|
||||||
|
|
||||||
fPixmap.reset();
|
fPixmap.reset();
|
||||||
fInvMatrix = inv;
|
fInvMatrix = inv;
|
||||||
fBilerp = false;
|
fBilerp = false;
|
||||||
|
|
||||||
fBMState = SkBitmapController::RequestBitmap(fImage, inv, sampling, &fAlloc);
|
auto* access = fAlloc.make<SkMipmapAccessor>(fImage, inv, sampling.mipmap);
|
||||||
|
std::tie(fPixmap, fInvMatrix) = access->level();
|
||||||
|
|
||||||
// Note : we allow the controller to return an empty (zero-dimension) result. Should we?
|
// Do we need this check?
|
||||||
if (nullptr == fBMState || fBMState->pixmap().info().isEmpty()) {
|
if (fPixmap.info().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fPixmap = fBMState->pixmap();
|
|
||||||
fInvMatrix = fBMState->invMatrix();
|
|
||||||
fPaintColor = paintColor;
|
fPaintColor = paintColor;
|
||||||
SkASSERT(!fBMState->sampling().useCubic);
|
fBilerp = sampling.filter == SkFilterMode::kLinear;
|
||||||
SkASSERT(fBMState->sampling().mipmap == SkMipmapMode::kNone);
|
|
||||||
fBilerp = fBMState->sampling().filter == SkFilterMode::kLinear;
|
|
||||||
SkASSERT(fPixmap.addr());
|
SkASSERT(fPixmap.addr());
|
||||||
|
|
||||||
bool integral_translate_only = just_trans_integral(fInvMatrix);
|
bool integral_translate_only = just_trans_integral(fInvMatrix);
|
||||||
|
@ -91,7 +91,6 @@ private:
|
|||||||
kBMStateSize = 136 // found by inspection. if too small, we will call new/delete
|
kBMStateSize = 136 // found by inspection. if too small, we will call new/delete
|
||||||
};
|
};
|
||||||
SkSTArenaAlloc<kBMStateSize> fAlloc;
|
SkSTArenaAlloc<kBMStateSize> fAlloc;
|
||||||
SkBitmapController::State* fBMState;
|
|
||||||
|
|
||||||
ShaderProc32 fShaderProc32; // chooseProcs
|
ShaderProc32 fShaderProc32; // chooseProcs
|
||||||
// These are used if the shaderproc is nullptr
|
// These are used if the shaderproc is nullptr
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "src/core/SkBitmapController.h"
|
#include "src/core/SkBitmapController.h"
|
||||||
#include "src/core/SkColorSpacePriv.h"
|
#include "src/core/SkColorSpacePriv.h"
|
||||||
#include "src/core/SkColorSpaceXformSteps.h"
|
#include "src/core/SkColorSpaceXformSteps.h"
|
||||||
|
#include "src/core/SkMatrixPriv.h"
|
||||||
#include "src/core/SkMatrixProvider.h"
|
#include "src/core/SkMatrixProvider.h"
|
||||||
#include "src/core/SkOpts.h"
|
#include "src/core/SkOpts.h"
|
||||||
#include "src/core/SkRasterPipeline.h"
|
#include "src/core/SkRasterPipeline.h"
|
||||||
@ -629,16 +630,14 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* state = SkBitmapController::RequestBitmap(as_IB(fImage.get()),
|
if (sampling.useCubic &&
|
||||||
matrix, sampling, alloc);
|
SkMatrixPriv::AdjustHighQualityFilterLevel(matrix, true) != kHigh_SkFilterQuality)
|
||||||
if (!state) {
|
{
|
||||||
return false;
|
sampling = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest);
|
||||||
}
|
}
|
||||||
|
auto* access = alloc->make<SkMipmapAccessor>(as_IB(fImage.get()), matrix, sampling.mipmap);
|
||||||
const SkPixmap& pm = state->pixmap();
|
SkPixmap pm;
|
||||||
matrix = state->invMatrix();
|
std::tie(pm, matrix) = access->level();
|
||||||
sampling = state->sampling();
|
|
||||||
auto info = pm.info();
|
|
||||||
|
|
||||||
p->append(SkRasterPipeline::seed_shader);
|
p->append(SkRasterPipeline::seed_shader);
|
||||||
|
|
||||||
@ -701,7 +700,7 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* ctx = gather;
|
void* ctx = gather;
|
||||||
switch (info.colorType()) {
|
switch (pm.colorType()) {
|
||||||
case kAlpha_8_SkColorType: p->append(SkRasterPipeline::gather_a8, ctx); break;
|
case kAlpha_8_SkColorType: p->append(SkRasterPipeline::gather_a8, ctx); break;
|
||||||
case kA16_unorm_SkColorType: p->append(SkRasterPipeline::gather_a16, ctx); break;
|
case kA16_unorm_SkColorType: p->append(SkRasterPipeline::gather_a16, ctx); break;
|
||||||
case kA16_float_SkColorType: p->append(SkRasterPipeline::gather_af16, ctx); break;
|
case kA16_float_SkColorType: p->append(SkRasterPipeline::gather_af16, ctx); break;
|
||||||
@ -745,11 +744,11 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto append_misc = [&] {
|
auto append_misc = [&] {
|
||||||
SkColorSpace* cs = info.colorSpace();
|
SkColorSpace* cs = pm.colorSpace();
|
||||||
SkAlphaType at = info.alphaType();
|
SkAlphaType at = pm.alphaType();
|
||||||
|
|
||||||
// Color for A8 images comes from the paint. TODO: all alpha images? none?
|
// Color for A8 images comes from the paint. TODO: all alpha images? none?
|
||||||
if (info.colorType() == kAlpha_8_SkColorType) {
|
if (pm.colorType() == kAlpha_8_SkColorType) {
|
||||||
SkColor4f rgb = rec.fPaint.getColor4f();
|
SkColor4f rgb = rec.fPaint.getColor4f();
|
||||||
p->append_set_rgb(alloc, rgb);
|
p->append_set_rgb(alloc, rgb);
|
||||||
|
|
||||||
@ -774,7 +773,7 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Check for fast-path stages.
|
// Check for fast-path stages.
|
||||||
auto ct = info.colorType();
|
auto ct = pm.colorType();
|
||||||
if (true
|
if (true
|
||||||
&& (ct == kRGBA_8888_SkColorType || ct == kBGRA_8888_SkColorType)
|
&& (ct == kRGBA_8888_SkColorType || ct == kBGRA_8888_SkColorType)
|
||||||
&& !sampling.useCubic && sampling.filter == SkFilterMode::kLinear
|
&& !sampling.useCubic && sampling.filter == SkFilterMode::kLinear
|
||||||
@ -901,40 +900,28 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
|
|||||||
}
|
}
|
||||||
baseInv.normalizePerspective();
|
baseInv.normalizePerspective();
|
||||||
|
|
||||||
const SkPixmap *upper = nullptr,
|
|
||||||
*lower = nullptr;
|
|
||||||
SkMatrix upperInv;
|
|
||||||
float lowerWeight = 0;
|
|
||||||
|
|
||||||
auto post_scale = [&](SkISize level, const SkMatrix& base) {
|
|
||||||
return SkMatrix::Scale(SkIntToScalar(level.width()) / fImage->width(),
|
|
||||||
SkIntToScalar(level.height()) / fImage->height())
|
|
||||||
* base;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto sampling = fUseSamplingOptions ? fSampling : SkSamplingOptions(paintQuality);
|
auto sampling = fUseSamplingOptions ? fSampling : SkSamplingOptions(paintQuality);
|
||||||
if (sampling.useCubic) {
|
auto* access = alloc->make<SkMipmapAccessor>(as_IB(fImage.get()), baseInv, sampling.mipmap);
|
||||||
auto* access = alloc->make<SkMipmapAccessor>(as_IB(fImage.get()), baseInv,
|
|
||||||
SkMipmapMode::kNone);
|
auto [upper, upperInv] = access->level();
|
||||||
upper = &access->level();
|
if (!sampling.useCubic) {
|
||||||
upperInv = post_scale(upper->dimensions(), baseInv);
|
|
||||||
} else {
|
|
||||||
auto* access = alloc->make<SkMipmapAccessor>(as_IB(fImage.get()), baseInv,
|
|
||||||
sampling.mipmap);
|
|
||||||
upper = &access->level();
|
|
||||||
upperInv = post_scale(upper->dimensions(), baseInv);
|
|
||||||
lowerWeight = access->lowerWeight();
|
|
||||||
if (lowerWeight > 0) {
|
|
||||||
lower = &access->lowerLevel();
|
|
||||||
}
|
|
||||||
sampling = tweak_filter_and_inv_matrix(sampling, &upperInv);
|
sampling = tweak_filter_and_inv_matrix(sampling, &upperInv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkPixmap lowerPixmap;
|
||||||
|
SkMatrix lowerInv;
|
||||||
|
SkPixmap* lower = nullptr;
|
||||||
|
float lowerWeight = access->lowerWeight();
|
||||||
|
if (lowerWeight > 0) {
|
||||||
|
std::tie(lowerPixmap, lowerInv) = access->lowerLevel();
|
||||||
|
lower = &lowerPixmap;
|
||||||
|
}
|
||||||
|
|
||||||
skvm::Coord upperLocal = SkShaderBase::ApplyMatrix(p, upperInv, origLocal, uniforms);
|
skvm::Coord upperLocal = SkShaderBase::ApplyMatrix(p, upperInv, origLocal, uniforms);
|
||||||
|
|
||||||
// All existing SkColorTypes pass these checks. We'd only fail here adding new ones.
|
// All existing SkColorTypes pass these checks. We'd only fail here adding new ones.
|
||||||
skvm::PixelFormat unused;
|
skvm::PixelFormat unused;
|
||||||
if (true && !SkColorType_to_PixelFormat(upper->colorType(), &unused)) {
|
if (true && !SkColorType_to_PixelFormat(upper.colorType(), &unused)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (lower && !SkColorType_to_PixelFormat(lower->colorType(), &unused)) {
|
if (lower && !SkColorType_to_PixelFormat(lower->colorType(), &unused)) {
|
||||||
@ -942,8 +929,8 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We can exploit image opacity to skip work unpacking alpha channels.
|
// We can exploit image opacity to skip work unpacking alpha channels.
|
||||||
const bool input_is_opaque = SkAlphaTypeIsOpaque(upper->alphaType())
|
const bool input_is_opaque = SkAlphaTypeIsOpaque(upper.alphaType())
|
||||||
|| SkColorTypeIsAlwaysOpaque(upper->colorType());
|
|| SkColorTypeIsAlwaysOpaque(upper.colorType());
|
||||||
|
|
||||||
// Each call to sample() will try to rewrite the same uniforms over and over,
|
// Each call to sample() will try to rewrite the same uniforms over and over,
|
||||||
// so remember where we start and reset back there each time. That way each
|
// so remember where we start and reset back there each time. That way each
|
||||||
@ -1121,9 +1108,8 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
skvm::Color c = sample_level(*upper, upperInv, upperLocal);
|
skvm::Color c = sample_level(upper, upperInv, upperLocal);
|
||||||
if (lower) {
|
if (lower) {
|
||||||
auto lowerInv = post_scale(lower->dimensions(), baseInv);
|
|
||||||
auto lowerLocal = SkShaderBase::ApplyMatrix(p, lowerInv, origLocal, uniforms);
|
auto lowerLocal = SkShaderBase::ApplyMatrix(p, lowerInv, origLocal, uniforms);
|
||||||
// lower * weight + upper * (1 - weight)
|
// lower * weight + upper * (1 - weight)
|
||||||
c = lerp(c,
|
c = lerp(c,
|
||||||
@ -1140,9 +1126,9 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Alpha-only images get their color from the paint (already converted to dst color space).
|
// Alpha-only images get their color from the paint (already converted to dst color space).
|
||||||
SkColorSpace* cs = upper->colorSpace();
|
SkColorSpace* cs = upper.colorSpace();
|
||||||
SkAlphaType at = upper->alphaType();
|
SkAlphaType at = upper.alphaType();
|
||||||
if (SkColorTypeIsAlphaOnly(upper->colorType())) {
|
if (SkColorTypeIsAlphaOnly(upper.colorType())) {
|
||||||
c.r = paint.r;
|
c.r = paint.r;
|
||||||
c.g = paint.g;
|
c.g = paint.g;
|
||||||
c.b = paint.b;
|
c.b = paint.b;
|
||||||
|
Loading…
Reference in New Issue
Block a user