Simplify GrSWMaskHelper
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1974943002 Review-Url: https://codereview.chromium.org/1974943002
This commit is contained in:
parent
f054b1766b
commit
9837740dd5
@ -98,8 +98,6 @@ DEFINE_double(overheadGoal, 0.0001,
|
||||
"Loop until timer overhead is at most this fraction of our measurments.");
|
||||
DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU.");
|
||||
DEFINE_int32(gpuFrameLag, 5, "If unknown, estimated maximum number of frames GPU allows to lag.");
|
||||
DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to "
|
||||
"software path rendering.");
|
||||
|
||||
DEFINE_string(outResultsFile, "", "If given, write results here as JSON.");
|
||||
DEFINE_int32(maxCalibrationAttempts, 3,
|
||||
@ -1036,7 +1034,6 @@ int nanobench_main() {
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
GrContextOptions grContextOpts;
|
||||
grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks;
|
||||
gGrFactory.reset(new GrContextFactory(grContextOpts));
|
||||
#endif
|
||||
|
||||
|
@ -255,10 +255,6 @@ public:
|
||||
|
||||
bool immediateFlush() const { return fImmediateFlush; }
|
||||
|
||||
bool drawPathMasksToCompressedTexturesSupport() const {
|
||||
return fDrawPathMasksToCompressedTextureSupport;
|
||||
}
|
||||
|
||||
size_t bufferMapThreshold() const {
|
||||
SkASSERT(fBufferMapThreshold >= 0);
|
||||
return fBufferMapThreshold;
|
||||
@ -333,7 +329,6 @@ private:
|
||||
|
||||
bool fSuppressPrints : 1;
|
||||
bool fImmediateFlush: 1;
|
||||
bool fDrawPathMasksToCompressedTextureSupport : 1;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
@ -12,8 +12,7 @@
|
||||
|
||||
struct GrContextOptions {
|
||||
GrContextOptions()
|
||||
: fDrawPathToCompressedTexture(false)
|
||||
, fSuppressPrints(false)
|
||||
: fSuppressPrints(false)
|
||||
, fMaxTextureSizeOverride(SK_MaxS32)
|
||||
, fMaxTileSizeOverride(0)
|
||||
, fSuppressDualSourceBlending(false)
|
||||
@ -26,11 +25,6 @@ struct GrContextOptions {
|
||||
, fMaxBatchLookahead(-1)
|
||||
, fUseShaderSwizzling(false) {}
|
||||
|
||||
// EXPERIMENTAL
|
||||
// May be removed in the future, or may become standard depending
|
||||
// on the outcomes of a variety of internal tests.
|
||||
bool fDrawPathToCompressedTexture;
|
||||
|
||||
// Suppress prints for the GrContext.
|
||||
bool fSuppressPrints;
|
||||
|
||||
|
@ -118,7 +118,6 @@ GrCaps::GrCaps(const GrContextOptions& options) {
|
||||
|
||||
fSuppressPrints = options.fSuppressPrints;
|
||||
fImmediateFlush = options.fImmediateMode;
|
||||
fDrawPathMasksToCompressedTextureSupport = options.fDrawPathToCompressedTexture;
|
||||
fBufferMapThreshold = options.fBufferMapThreshold;
|
||||
fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite;
|
||||
fUseDrawInsteadOfAllRenderTargetWrites = false;
|
||||
|
@ -861,7 +861,7 @@ GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
|
||||
SkMatrix translate;
|
||||
translate.setTranslate(clipToMaskOffset);
|
||||
|
||||
helper.init(maskSpaceIBounds, &translate, false);
|
||||
helper.init(maskSpaceIBounds, &translate);
|
||||
helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x00);
|
||||
|
||||
for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get(); iter.next()) {
|
||||
@ -876,24 +876,24 @@ GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
|
||||
if (SkRegion::kReverseDifference_Op == op) {
|
||||
SkRect temp = SkRect::Make(clipSpaceIBounds);
|
||||
// invert the entire scene
|
||||
helper.draw(temp, SkRegion::kXOR_Op, false, 0xFF);
|
||||
helper.drawRect(temp, SkRegion::kXOR_Op, false, 0xFF);
|
||||
}
|
||||
SkPath clipPath;
|
||||
element->asPath(&clipPath);
|
||||
clipPath.toggleInverseFillType();
|
||||
helper.draw(clipPath, GrStyle::SimpleFill(), SkRegion::kReplace_Op, element->isAA(),
|
||||
0x00);
|
||||
helper.drawPath(clipPath, GrStyle::SimpleFill(), SkRegion::kReplace_Op,
|
||||
element->isAA(), 0x00);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The other ops (union, xor, diff) only affect pixels inside
|
||||
// the geometry so they can just be drawn normally
|
||||
if (Element::kRect_Type == element->getType()) {
|
||||
helper.draw(element->getRect(), op, element->isAA(), 0xFF);
|
||||
helper.drawRect(element->getRect(), op, element->isAA(), 0xFF);
|
||||
} else {
|
||||
SkPath path;
|
||||
element->asPath(&path);
|
||||
helper.draw(path, GrStyle::SimpleFill(), op, element->isAA(), 0xFF);
|
||||
helper.drawPath(path, GrStyle::SimpleFill(), op, element->isAA(), 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,10 @@
|
||||
|
||||
#include "batches/GrRectBatchFactory.h"
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Convert a boolean operation into a transfer mode code
|
||||
*/
|
||||
SkXfermode::Mode op_to_mode(SkRegion::Op op) {
|
||||
static SkXfermode::Mode op_to_mode(SkRegion::Op op) {
|
||||
|
||||
static const SkXfermode::Mode modeMap[] = {
|
||||
SkXfermode::kDstOut_Mode, // kDifference_Op
|
||||
@ -38,76 +36,13 @@ SkXfermode::Mode op_to_mode(SkRegion::Op op) {
|
||||
return modeMap[op];
|
||||
}
|
||||
|
||||
static inline GrPixelConfig fmt_to_config(SkTextureCompressor::Format fmt) {
|
||||
|
||||
GrPixelConfig config;
|
||||
switch (fmt) {
|
||||
case SkTextureCompressor::kLATC_Format:
|
||||
config = kLATC_GrPixelConfig;
|
||||
break;
|
||||
|
||||
case SkTextureCompressor::kR11_EAC_Format:
|
||||
config = kR11_EAC_GrPixelConfig;
|
||||
break;
|
||||
|
||||
case SkTextureCompressor::kASTC_12x12_Format:
|
||||
config = kASTC_12x12_GrPixelConfig;
|
||||
break;
|
||||
|
||||
case SkTextureCompressor::kETC1_Format:
|
||||
config = kETC1_GrPixelConfig;
|
||||
break;
|
||||
|
||||
default:
|
||||
SkDEBUGFAIL("No GrPixelConfig for compression format!");
|
||||
// Best guess
|
||||
config = kAlpha_8_GrPixelConfig;
|
||||
break;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
static bool choose_compressed_fmt(const GrCaps* caps,
|
||||
SkTextureCompressor::Format *fmt) {
|
||||
if (nullptr == fmt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can't use scratch textures without the ability to update
|
||||
// compressed textures...
|
||||
if (!(caps->compressedTexSubImageSupport())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Figure out what our preferred texture type is. If ASTC is available, that always
|
||||
// gives the biggest win. Otherwise, in terms of compression speed and accuracy,
|
||||
// LATC has a slight edge over R11 EAC.
|
||||
if (caps->isConfigTexturable(kASTC_12x12_GrPixelConfig)) {
|
||||
*fmt = SkTextureCompressor::kASTC_12x12_Format;
|
||||
return true;
|
||||
} else if (caps->isConfigTexturable(kLATC_GrPixelConfig)) {
|
||||
*fmt = SkTextureCompressor::kLATC_Format;
|
||||
return true;
|
||||
} else if (caps->isConfigTexturable(kR11_EAC_GrPixelConfig)) {
|
||||
*fmt = SkTextureCompressor::kR11_EAC_Format;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a single rect element of the clip stack into the accumulation bitmap
|
||||
*/
|
||||
void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op,
|
||||
bool antiAlias, uint8_t alpha) {
|
||||
void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op,
|
||||
bool antiAlias, uint8_t alpha) {
|
||||
SkPaint paint;
|
||||
|
||||
SkASSERT(kNone_CompressionMode == fCompressionMode);
|
||||
|
||||
paint.setXfermode(SkXfermode::Make(op_to_mode(op)));
|
||||
paint.setAntiAlias(antiAlias);
|
||||
paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
|
||||
@ -118,35 +53,24 @@ void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op,
|
||||
/**
|
||||
* Draw a single path element of the clip stack into the accumulation bitmap
|
||||
*/
|
||||
void GrSWMaskHelper::draw(const SkPath& path, const GrStyle& style, SkRegion::Op op,
|
||||
bool antiAlias, uint8_t alpha) {
|
||||
void GrSWMaskHelper::drawPath(const SkPath& path, const GrStyle& style, SkRegion::Op op,
|
||||
bool antiAlias, uint8_t alpha) {
|
||||
SkPaint paint;
|
||||
paint.setPathEffect(sk_ref_sp(style.pathEffect()));
|
||||
style.strokeRec().applyToPaint(&paint);
|
||||
paint.setAntiAlias(antiAlias);
|
||||
|
||||
SkTBlitterAllocator allocator;
|
||||
SkBlitter* blitter = nullptr;
|
||||
if (kBlitter_CompressionMode == fCompressionMode) {
|
||||
SkASSERT(fCompressedBuffer.get());
|
||||
blitter = SkTextureCompressor::CreateBlitterForFormat(
|
||||
fPixels.width(), fPixels.height(), fCompressedBuffer.get(), &allocator,
|
||||
fCompressedFormat);
|
||||
}
|
||||
|
||||
if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
|
||||
SkASSERT(0xFF == paint.getAlpha());
|
||||
fDraw.drawPathCoverage(path, paint, blitter);
|
||||
fDraw.drawPathCoverage(path, paint);
|
||||
} else {
|
||||
paint.setXfermodeMode(op_to_mode(op));
|
||||
paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
|
||||
fDraw.drawPath(path, paint, blitter);
|
||||
fDraw.drawPath(path, paint);
|
||||
}
|
||||
}
|
||||
|
||||
bool GrSWMaskHelper::init(const SkIRect& resultBounds,
|
||||
const SkMatrix* matrix,
|
||||
bool allowCompression) {
|
||||
bool GrSWMaskHelper::init(const SkIRect& resultBounds, const SkMatrix* matrix) {
|
||||
if (matrix) {
|
||||
fMatrix = *matrix;
|
||||
} else {
|
||||
@ -154,54 +78,16 @@ bool GrSWMaskHelper::init(const SkIRect& resultBounds,
|
||||
}
|
||||
|
||||
// Now translate so the bound's UL corner is at the origin
|
||||
fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1,
|
||||
-resultBounds.fTop * SK_Scalar1);
|
||||
SkIRect bounds = SkIRect::MakeWH(resultBounds.width(),
|
||||
resultBounds.height());
|
||||
fMatrix.postTranslate(-SkIntToScalar(resultBounds.fLeft), -SkIntToScalar(resultBounds.fTop));
|
||||
SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height());
|
||||
|
||||
if (allowCompression &&
|
||||
fContext->caps()->drawPathMasksToCompressedTexturesSupport() &&
|
||||
choose_compressed_fmt(fContext->caps(), &fCompressedFormat)) {
|
||||
fCompressionMode = kCompress_CompressionMode;
|
||||
}
|
||||
|
||||
// Make sure that the width is a multiple of the desired block dimensions
|
||||
// to allow for specialized SIMD instructions that compress multiple blocks at a time.
|
||||
int cmpWidth = bounds.fRight;
|
||||
int cmpHeight = bounds.fBottom;
|
||||
if (kCompress_CompressionMode == fCompressionMode) {
|
||||
int dimX, dimY;
|
||||
SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY);
|
||||
cmpWidth = dimX * ((cmpWidth + (dimX - 1)) / dimX);
|
||||
cmpHeight = dimY * ((cmpHeight + (dimY - 1)) / dimY);
|
||||
|
||||
// Can we create a blitter?
|
||||
if (SkTextureCompressor::ExistsBlitterForFormat(fCompressedFormat)) {
|
||||
int cmpSz = SkTextureCompressor::GetCompressedDataSize(
|
||||
fCompressedFormat, cmpWidth, cmpHeight);
|
||||
|
||||
SkASSERT(cmpSz > 0);
|
||||
SkASSERT(nullptr == fCompressedBuffer.get());
|
||||
fCompressedBuffer.reset(cmpSz);
|
||||
fCompressionMode = kBlitter_CompressionMode;
|
||||
}
|
||||
const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(bounds.width(), bounds.height());
|
||||
if (!fPixels.tryAlloc(bmImageInfo)) {
|
||||
return false;
|
||||
}
|
||||
fPixels.erase(0);
|
||||
|
||||
sk_bzero(&fDraw, sizeof(fDraw));
|
||||
|
||||
// If we don't have a custom blitter, then we either need a bitmap to compress
|
||||
// from or a bitmap that we're going to use as a texture. In any case, we should
|
||||
// allocate the pixels for a bitmap
|
||||
const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(cmpWidth, cmpHeight);
|
||||
if (kBlitter_CompressionMode != fCompressionMode) {
|
||||
if (!fPixels.tryAlloc(bmImageInfo)) {
|
||||
return false;
|
||||
}
|
||||
fPixels.erase(0);
|
||||
} else {
|
||||
// Otherwise, we just need to remember how big the buffer is...
|
||||
fPixels.reset(bmImageInfo);
|
||||
}
|
||||
fDraw.fDst = fPixels;
|
||||
fRasterClip.setRect(bounds);
|
||||
fDraw.fRC = &fRasterClip;
|
||||
@ -218,67 +104,20 @@ GrTexture* GrSWMaskHelper::createTexture() {
|
||||
desc.fHeight = fPixels.height();
|
||||
desc.fConfig = kAlpha_8_GrPixelConfig;
|
||||
|
||||
if (kNone_CompressionMode != fCompressionMode) {
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
int dimX, dimY;
|
||||
SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY);
|
||||
SkASSERT((desc.fWidth % dimX) == 0);
|
||||
SkASSERT((desc.fHeight % dimY) == 0);
|
||||
#endif
|
||||
|
||||
desc.fConfig = fmt_to_config(fCompressedFormat);
|
||||
SkASSERT(fContext->caps()->isConfigTexturable(desc.fConfig));
|
||||
}
|
||||
|
||||
return fContext->textureProvider()->createApproxTexture(desc);
|
||||
}
|
||||
|
||||
void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrSurfaceDesc& desc,
|
||||
const void *data, size_t rowbytes) {
|
||||
// Since we're uploading to it, and it's compressed, 'texture' shouldn't
|
||||
// have a render target.
|
||||
SkASSERT(nullptr == texture->asRenderTarget());
|
||||
|
||||
texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, data, rowbytes);
|
||||
}
|
||||
|
||||
void GrSWMaskHelper::compressTextureData(GrTexture *texture, const GrSurfaceDesc& desc) {
|
||||
|
||||
SkASSERT(GrPixelConfigIsCompressed(desc.fConfig));
|
||||
SkASSERT(fmt_to_config(fCompressedFormat) == desc.fConfig);
|
||||
|
||||
SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fPixels,
|
||||
fCompressedFormat));
|
||||
SkASSERT(cmpData);
|
||||
|
||||
this->sendTextureData(texture, desc, cmpData->data(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the result of the software mask generation back to the gpu
|
||||
*/
|
||||
void GrSWMaskHelper::toTexture(GrTexture *texture) {
|
||||
GrSurfaceDesc desc;
|
||||
desc.fWidth = fPixels.width();
|
||||
desc.fHeight = fPixels.height();
|
||||
desc.fConfig = texture->config();
|
||||
// Since we're uploading to it, and it's compressed, 'texture' shouldn't
|
||||
// have a render target.
|
||||
SkASSERT(!texture->asRenderTarget());
|
||||
|
||||
// First see if we should compress this texture before uploading.
|
||||
switch (fCompressionMode) {
|
||||
case kNone_CompressionMode:
|
||||
this->sendTextureData(texture, desc, fPixels.addr(), fPixels.rowBytes());
|
||||
break;
|
||||
texture->writePixels(0, 0, fPixels.width(), fPixels.height(), texture->config(),
|
||||
fPixels.addr(), fPixels.rowBytes());
|
||||
|
||||
case kCompress_CompressionMode:
|
||||
this->compressTextureData(texture, desc);
|
||||
break;
|
||||
|
||||
case kBlitter_CompressionMode:
|
||||
SkASSERT(fCompressedBuffer.get());
|
||||
this->sendTextureData(texture, desc, fCompressedBuffer.get(), 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,7 +146,7 @@ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
helper.draw(path, style, SkRegion::kReplace_Op, antiAlias, 0xFF);
|
||||
helper.drawPath(path, style, SkRegion::kReplace_Op, antiAlias, 0xFF);
|
||||
|
||||
GrTexture* texture(helper.createTexture());
|
||||
if (!texture) {
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "SkMatrix.h"
|
||||
#include "SkRasterClip.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkTextureCompressor.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
class GrClip;
|
||||
@ -42,24 +41,20 @@ class GrDrawTarget;
|
||||
*/
|
||||
class GrSWMaskHelper : SkNoncopyable {
|
||||
public:
|
||||
GrSWMaskHelper(GrContext* context)
|
||||
: fContext(context)
|
||||
, fCompressionMode(kNone_CompressionMode) {
|
||||
}
|
||||
GrSWMaskHelper(GrContext* context) : fContext(context) { }
|
||||
|
||||
// set up the internal state in preparation for draws. Since many masks
|
||||
// may be accumulated in the helper during creation, "resultBounds"
|
||||
// allows the caller to specify the region of interest - to limit the
|
||||
// amount of work. allowCompression should be set to false if you plan on using
|
||||
// your own texture to draw into, and not a scratch texture via getTexture().
|
||||
bool init(const SkIRect& resultBounds, const SkMatrix* matrix, bool allowCompression = true);
|
||||
// amount of work.
|
||||
bool init(const SkIRect& resultBounds, const SkMatrix* matrix);
|
||||
|
||||
// Draw a single rect into the accumulation bitmap using the specified op
|
||||
void draw(const SkRect& rect, SkRegion::Op op, bool antiAlias, uint8_t alpha);
|
||||
void drawRect(const SkRect& rect, SkRegion::Op op, bool antiAlias, uint8_t alpha);
|
||||
|
||||
// Draw a single path into the accumuation bitmap using the specified op
|
||||
void draw(const SkPath& path, const GrStyle& style, SkRegion::Op op,
|
||||
bool antiAlias, uint8_t alpha);
|
||||
void drawPath(const SkPath& path, const GrStyle& style, SkRegion::Op op,
|
||||
bool antiAlias, uint8_t alpha);
|
||||
|
||||
// Move the mask generation results from the internal bitmap to the gpu.
|
||||
void toTexture(GrTexture* texture);
|
||||
@ -110,33 +105,6 @@ private:
|
||||
SkDraw fDraw;
|
||||
SkRasterClip fRasterClip;
|
||||
|
||||
// This enum says whether or not we should compress the mask:
|
||||
// kNone_CompressionMode: compression is not supported on this device.
|
||||
// kCompress_CompressionMode: compress the bitmap before it gets sent to the gpu
|
||||
// kBlitter_CompressionMode: write to the bitmap using a special compressed blitter.
|
||||
enum CompressionMode {
|
||||
kNone_CompressionMode,
|
||||
kCompress_CompressionMode,
|
||||
kBlitter_CompressionMode,
|
||||
} fCompressionMode;
|
||||
|
||||
// This is the buffer into which we store our compressed data. This buffer is
|
||||
// only allocated (non-null) if fCompressionMode is kBlitter_CompressionMode
|
||||
SkAutoMalloc fCompressedBuffer;
|
||||
|
||||
// This is the desired format within which to compress the
|
||||
// texture. This value is only valid if fCompressionMode is not kNone_CompressionMode.
|
||||
SkTextureCompressor::Format fCompressedFormat;
|
||||
|
||||
// Actually sends the texture data to the GPU. This is called from
|
||||
// toTexture with the data filled in depending on the texture config.
|
||||
void sendTextureData(GrTexture *texture, const GrSurfaceDesc& desc,
|
||||
const void *data, size_t rowbytes);
|
||||
|
||||
// Compresses the bitmap stored in fBM and sends the compressed data
|
||||
// to the GPU to be stored in 'texture' using sendTextureData.
|
||||
void compressTextureData(GrTexture *texture, const GrSurfaceDesc& desc);
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkResourceCache.h"
|
||||
#include "SkTemplates.h"
|
||||
#include "SkTextureCompressor.h"
|
||||
#include "SkYUVPlanesCache.h"
|
||||
#include "effects/GrBicubicEffect.h"
|
||||
#include "effects/GrConstColorProcessor.h"
|
||||
|
Loading…
Reference in New Issue
Block a user