robertphillips 2016-05-13 05:47:23 -07:00 committed by Commit bot
parent f054b1766b
commit 9837740dd5
8 changed files with 33 additions and 242 deletions

View File

@ -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

View File

@ -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;
};

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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;
};

View File

@ -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"