Revert "Migrate uses of deferred proxies to lazy proxies"
This reverts commit 990a0d8b65
.
Reason for revert: Keeping it. Deferred proxies are uploaded later than lazy and we want that for this use case.
Original change's description:
> Migrate uses of deferred proxies to lazy proxies
>
> A follow-up CL removes the deferred proxies system entirely.
>
> Bug: skia:11288
> Change-Id: Ic5b3ce820ea946f6ae27bd763c0f389caf8863d1
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366716
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Adlai Holler <adlai@google.com>
TBR=bsalomon@google.com,robertphillips@google.com,adlai@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: skia:11288
Change-Id: I9ced532d013805afae3b20baa53cab31cae2b953
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/368797
Reviewed-by: Adlai Holler <adlai@google.com>
Commit-Queue: Adlai Holler <adlai@google.com>
This commit is contained in:
parent
4908a24d4b
commit
cc25d53420
@ -22,6 +22,7 @@
|
||||
|
||||
struct SkIRect;
|
||||
|
||||
class GrTexture;
|
||||
class SkDiscardableMemory;
|
||||
|
||||
/** \class SkPixelRef
|
||||
|
@ -19,7 +19,7 @@ class GrBitmapTextureMaker final : public GrTextureMaker {
|
||||
public:
|
||||
GrBitmapTextureMaker(GrRecordingContext*, const SkBitmap&, GrImageTexGenPolicy);
|
||||
|
||||
// Always uncached-budgeted. It doesn't make sense to have kApprox cached textures. Moreover, we
|
||||
// Always uncached-budgeted. It doesn't make sense to have kApprox cached textures. Moreover,we
|
||||
// create kApprox textures intermediate buffers and those ought to be budgeted.
|
||||
GrBitmapTextureMaker(GrRecordingContext*, const SkBitmap&, SkBackingFit);
|
||||
|
||||
|
@ -317,19 +317,62 @@ static GrSurfaceProxyView render_sw_mask(GrRecordingContext* context, const SkIR
|
||||
const GrClipStack::Element** elements, int count) {
|
||||
SkASSERT(count > 0);
|
||||
|
||||
SkTArray<GrClipStack::Element> data(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
data.push_back(*(elements[i]));
|
||||
SkTaskGroup* taskGroup = nullptr;
|
||||
if (auto direct = context->asDirectContext()) {
|
||||
taskGroup = direct->priv().getTaskGroup();
|
||||
}
|
||||
return GrSWMaskHelper::MakeTexture(bounds,
|
||||
context,
|
||||
SkBackingFit::kApprox,
|
||||
[data{std::move(data)}](GrSWMaskHelper* helper) {
|
||||
TRACE_EVENT0("skia.gpu", "SW Clip Mask Render");
|
||||
for (int i = 0; i < data.count(); ++i) {
|
||||
draw_to_sw_mask(helper, data[i], i == 0);
|
||||
|
||||
if (taskGroup) {
|
||||
const GrCaps* caps = context->priv().caps();
|
||||
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
|
||||
|
||||
// Create our texture proxy
|
||||
GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
|
||||
GrRenderable::kNo);
|
||||
|
||||
GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(format, GrColorType::kAlpha_8);
|
||||
auto proxy = proxyProvider->createProxy(format, bounds.size(), GrRenderable::kNo, 1,
|
||||
GrMipMapped::kNo, SkBackingFit::kApprox,
|
||||
SkBudgeted::kYes, GrProtected::kNo);
|
||||
|
||||
// Since this will be rendered on another thread, make a copy of the elements in case
|
||||
// the clip stack is modified on the main thread
|
||||
using Uploader = GrTDeferredProxyUploader<SkTArray<GrClipStack::Element>>;
|
||||
std::unique_ptr<Uploader> uploader = std::make_unique<Uploader>(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
uploader->data().push_back(*(elements[i]));
|
||||
}
|
||||
});
|
||||
|
||||
Uploader* uploaderRaw = uploader.get();
|
||||
auto drawAndUploadMask = [uploaderRaw, bounds] {
|
||||
TRACE_EVENT0("skia.gpu", "Threaded SW Clip Mask Render");
|
||||
GrSWMaskHelper helper(uploaderRaw->getPixels());
|
||||
if (helper.init(bounds)) {
|
||||
for (int i = 0; i < uploaderRaw->data().count(); ++i) {
|
||||
draw_to_sw_mask(&helper, uploaderRaw->data()[i], i == 0);
|
||||
}
|
||||
} else {
|
||||
SkDEBUGFAIL("Unable to allocate SW clip mask.");
|
||||
}
|
||||
uploaderRaw->signalAndFreeData();
|
||||
};
|
||||
|
||||
taskGroup->add(std::move(drawAndUploadMask));
|
||||
proxy->texPriv().setDeferredUploader(std::move(uploader));
|
||||
|
||||
return {std::move(proxy), kMaskOrigin, swizzle};
|
||||
} else {
|
||||
GrSWMaskHelper helper;
|
||||
if (!helper.init(bounds)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
draw_to_sw_mask(&helper,*(elements[i]), i == 0);
|
||||
}
|
||||
|
||||
return helper.toTextureView(context, SkBackingFit::kApprox);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_stencil_mask(GrRecordingContext* context, GrSurfaceDrawContext* rtc,
|
||||
|
@ -380,7 +380,7 @@ GrSurfaceProxyView GrClipStackClip::createAlphaClipMask(GrRecordingContext* cont
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Payload class for use with GrSWMaskHelper. The clip mask code renders multiple
|
||||
* Payload class for use with GrTDeferredProxyUploader. The clip mask code renders multiple
|
||||
* elements, each storing their own AA setting (and already transformed into device space). This
|
||||
* stores all of the information needed by the worker thread to draw all clip elements (see below,
|
||||
* in createSoftwareClipMask).
|
||||
@ -468,17 +468,61 @@ GrSurfaceProxyView GrClipStackClip::createSoftwareClipMask(
|
||||
// left corner of the resulting rect to the top left of the texture.
|
||||
SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.height());
|
||||
|
||||
std::shared_ptr<ClipMaskData> data = std::make_shared<ClipMaskData>(reducedClip);
|
||||
auto view = GrSWMaskHelper::MakeTexture(maskSpaceIBounds,
|
||||
context,
|
||||
SkBackingFit::kApprox,
|
||||
[data{std::move(data)}](GrSWMaskHelper* helper) {
|
||||
TRACE_EVENT0("skia.gpu", "SW Clip Mask Render");
|
||||
draw_clip_elements_to_mask_helper(*helper,
|
||||
data->elements(),
|
||||
data->scissor(),
|
||||
data->initialState());
|
||||
});
|
||||
SkTaskGroup* taskGroup = nullptr;
|
||||
if (auto direct = context->asDirectContext()) {
|
||||
taskGroup = direct->priv().getTaskGroup();
|
||||
}
|
||||
|
||||
GrSurfaceProxyView view;
|
||||
if (taskGroup && surfaceDrawContext) {
|
||||
const GrCaps* caps = context->priv().caps();
|
||||
// Create our texture proxy
|
||||
GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
|
||||
GrRenderable::kNo);
|
||||
|
||||
GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(format, GrColorType::kAlpha_8);
|
||||
|
||||
// MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt
|
||||
// to ops), so it can't have any pending IO.
|
||||
auto proxy = proxyProvider->createProxy(format,
|
||||
maskSpaceIBounds.size(),
|
||||
GrRenderable::kNo,
|
||||
1,
|
||||
GrMipmapped::kNo,
|
||||
SkBackingFit::kApprox,
|
||||
SkBudgeted::kYes,
|
||||
GrProtected::kNo);
|
||||
|
||||
auto uploader = std::make_unique<GrTDeferredProxyUploader<ClipMaskData>>(reducedClip);
|
||||
GrTDeferredProxyUploader<ClipMaskData>* uploaderRaw = uploader.get();
|
||||
auto drawAndUploadMask = [uploaderRaw, maskSpaceIBounds] {
|
||||
TRACE_EVENT0("skia.gpu", "Threaded SW Clip Mask Render");
|
||||
GrSWMaskHelper helper(uploaderRaw->getPixels());
|
||||
if (helper.init(maskSpaceIBounds)) {
|
||||
draw_clip_elements_to_mask_helper(helper, uploaderRaw->data().elements(),
|
||||
uploaderRaw->data().scissor(),
|
||||
uploaderRaw->data().initialState());
|
||||
} else {
|
||||
SkDEBUGFAIL("Unable to allocate SW clip mask.");
|
||||
}
|
||||
uploaderRaw->signalAndFreeData();
|
||||
};
|
||||
|
||||
taskGroup->add(std::move(drawAndUploadMask));
|
||||
proxy->texPriv().setDeferredUploader(std::move(uploader));
|
||||
|
||||
view = {std::move(proxy), kMaskOrigin, swizzle};
|
||||
} else {
|
||||
GrSWMaskHelper helper;
|
||||
if (!helper.init(maskSpaceIBounds)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
draw_clip_elements_to_mask_helper(helper, reducedClip.maskElements(), reducedClip.scissor(),
|
||||
reducedClip.initialState());
|
||||
|
||||
view = helper.toTextureView(context, SkBackingFit::kApprox);
|
||||
}
|
||||
|
||||
SkASSERT(view);
|
||||
SkASSERT(view.origin() == kMaskOrigin);
|
||||
|
@ -9,10 +9,8 @@
|
||||
|
||||
#include "include/gpu/GrRecordingContext.h"
|
||||
#include "src/core/SkMatrixProvider.h"
|
||||
#include "src/core/SkTaskGroup.h"
|
||||
#include "src/gpu/GrBitmapTextureMaker.h"
|
||||
#include "src/gpu/GrCaps.h"
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
#include "src/gpu/GrProxyProvider.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrSurfaceContext.h"
|
||||
@ -45,96 +43,6 @@ static SkPaint get_paint(SkRegion::Op op, GrAA aa, uint8_t alpha) {
|
||||
return paint;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView GrSWMaskHelper::MakeTexture(SkIRect bounds,
|
||||
GrRecordingContext* context,
|
||||
SkBackingFit fit,
|
||||
DrawFunc&& draw) {
|
||||
SkTaskGroup* taskGroup = nullptr;
|
||||
if (auto dContext = context->asDirectContext()) {
|
||||
taskGroup = dContext->priv().getTaskGroup();
|
||||
}
|
||||
if (taskGroup) {
|
||||
GrSWMaskHelper* helper = new GrSWMaskHelper(bounds);
|
||||
return helper->threadedExecute(taskGroup, context, fit, std::move(draw));
|
||||
} else {
|
||||
GrSWMaskHelper helper(bounds);
|
||||
return helper.nonThreadedExecute(context, fit, draw);
|
||||
}
|
||||
}
|
||||
|
||||
GrSurfaceProxyView GrSWMaskHelper::threadedExecute(SkTaskGroup* taskGroup,
|
||||
GrRecordingContext* context,
|
||||
SkBackingFit fit,
|
||||
DrawFunc&& draw) {
|
||||
sk_sp<GrSWMaskHelper> spThis(this);
|
||||
taskGroup->add([spThis, draw{std::move(draw)}]() {
|
||||
if (spThis->allocate()) {
|
||||
draw(spThis.get());
|
||||
spThis->fBitmap.setImmutable();
|
||||
}
|
||||
spThis->fSemaphore.signal();
|
||||
});
|
||||
auto lazy_cb = [spThis{std::move(spThis)}](GrResourceProvider* provider,
|
||||
const GrProxyProvider::LazySurfaceDesc& desc) {
|
||||
spThis->fSemaphore.wait();
|
||||
const SkBitmap& mask = spThis->fBitmap;
|
||||
if (!mask.getPixels()) {
|
||||
return GrProxyProvider::LazyCallbackResult();
|
||||
}
|
||||
GrMipLevel mip{mask.getPixels(), mask.pixmap().rowBytes()};
|
||||
GrColorType ct{SkColorTypeToGrColorType(mask.colorType())};
|
||||
sk_sp<GrTexture> tex = provider->createTexture(desc.fDimensions,
|
||||
desc.fFormat,
|
||||
ct,
|
||||
desc.fRenderable,
|
||||
desc.fSampleCnt,
|
||||
desc.fBudgeted,
|
||||
desc.fFit,
|
||||
desc.fProtected,
|
||||
mip);
|
||||
GrProxyProvider::LazyCallbackResult result(std::move(tex));
|
||||
// Callback refs us, we own bitmap, don't release callback.
|
||||
result.fReleaseCallback = false;
|
||||
return result;
|
||||
};
|
||||
const GrCaps* caps = context->priv().caps();
|
||||
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
|
||||
|
||||
GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
|
||||
GrRenderable::kNo);
|
||||
GrSwizzle swizzle = caps->getReadSwizzle(format, GrColorType::kAlpha_8);
|
||||
sk_sp<GrTextureProxy> p = proxyProvider->createLazyProxy(std::move(lazy_cb),
|
||||
format,
|
||||
fBitmap.dimensions(),
|
||||
GrMipMapped::kNo,
|
||||
GrMipmapStatus::kNotAllocated,
|
||||
GrInternalSurfaceFlags::kNone,
|
||||
fit,
|
||||
SkBudgeted::kYes,
|
||||
GrProtected::kNo,
|
||||
GrProxyProvider::UseAllocator::kYes);
|
||||
return GrSurfaceProxyView(std::move(p), kTopLeft_GrSurfaceOrigin, swizzle);
|
||||
}
|
||||
|
||||
GrSurfaceProxyView GrSWMaskHelper::nonThreadedExecute(GrRecordingContext* context,
|
||||
SkBackingFit fit,
|
||||
const DrawFunc& draw) {
|
||||
if (!this->allocate()) {
|
||||
return {};
|
||||
}
|
||||
draw(this);
|
||||
fBitmap.setImmutable();
|
||||
GrBitmapTextureMaker maker(context, fBitmap, fit);
|
||||
return maker.view(GrMipmapped::kNo);
|
||||
}
|
||||
|
||||
GrSWMaskHelper::GrSWMaskHelper(const SkIRect& resultBounds) {
|
||||
// We will need to translate draws so the bound's UL corner is at the origin
|
||||
fTranslate = {-SkIntToScalar(resultBounds.fLeft), -SkIntToScalar(resultBounds.fTop)};
|
||||
SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height());
|
||||
fBitmap.setInfo(SkImageInfo::MakeA8(bounds.width(), bounds.height()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a single rect element of the clip stack into the accumulation bitmap
|
||||
*/
|
||||
@ -220,14 +128,33 @@ void GrSWMaskHelper::drawShape(const GrShape& shape, const SkMatrix& matrix, SkR
|
||||
}
|
||||
}
|
||||
|
||||
bool GrSWMaskHelper::allocate() {
|
||||
if (!fBitmap.tryAllocPixels()) {
|
||||
SkDEBUGFAIL("Unable to allocate SW mask.");
|
||||
bool GrSWMaskHelper::init(const SkIRect& resultBounds) {
|
||||
// We will need to translate draws so the bound's UL corner is at the origin
|
||||
fTranslate = {-SkIntToScalar(resultBounds.fLeft), -SkIntToScalar(resultBounds.fTop)};
|
||||
SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height());
|
||||
|
||||
const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(bounds.width(), bounds.height());
|
||||
if (!fPixels->tryAlloc(bmImageInfo)) {
|
||||
return false;
|
||||
}
|
||||
fPixels->erase(0);
|
||||
|
||||
fDraw.fDst = fBitmap.pixmap();
|
||||
fRasterClip.setRect(fBitmap.info().bounds());
|
||||
fDraw.fDst = *fPixels;
|
||||
fRasterClip.setRect(bounds);
|
||||
fDraw.fRC = &fRasterClip;
|
||||
return true;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView GrSWMaskHelper::toTextureView(GrRecordingContext* context, SkBackingFit fit) {
|
||||
SkImageInfo ii = SkImageInfo::MakeA8(fPixels->width(), fPixels->height());
|
||||
size_t rowBytes = fPixels->rowBytes();
|
||||
|
||||
SkBitmap bitmap;
|
||||
SkAssertResult(bitmap.installPixels(ii, fPixels->detachPixels(), rowBytes,
|
||||
[](void* addr, void* context) { sk_free(addr); },
|
||||
nullptr));
|
||||
bitmap.setImmutable();
|
||||
|
||||
GrBitmapTextureMaker maker(context, bitmap, fit);
|
||||
return maker.view(GrMipmapped::kNo);
|
||||
}
|
||||
|
@ -21,37 +21,31 @@ class GrShape;
|
||||
class GrStyledShape;
|
||||
class GrRecordingContext;
|
||||
class GrTextureProxy;
|
||||
class SkTaskGroup;
|
||||
|
||||
/**
|
||||
* The GrSWMaskHelper helps generate clip masks using the software rendering
|
||||
* path. It is intended to be used as:
|
||||
*
|
||||
* auto data = copy_required_drawing_data();
|
||||
* GrSurfaceProxyView proxy
|
||||
* = GrSWMaskHelper::MakeTexture(bounds,
|
||||
* context,
|
||||
* SkBackingFit::kApprox/kExact,
|
||||
* [data{std::move(data)}](GrSWMaskHelper* helper) {
|
||||
* // draw one or more paths/rects specifying the required boolean ops
|
||||
* helper->drawRect(data.rect(), ...);
|
||||
* });
|
||||
* GrSWMaskHelper helper(context);
|
||||
* helper.init(...);
|
||||
*
|
||||
* draw one or more paths/rects specifying the required boolean ops
|
||||
*
|
||||
* toTextureView(); // to get it from the internal bitmap to the GPU
|
||||
*
|
||||
* The result of this process will be the final mask (on the GPU) in the
|
||||
* upper left hand corner of the texture.
|
||||
*/
|
||||
class GrSWMaskHelper : public SkNVRefCnt<GrSWMaskHelper> {
|
||||
class GrSWMaskHelper : SkNoncopyable {
|
||||
public:
|
||||
using DrawFunc = std::function<void(GrSWMaskHelper*)>;
|
||||
GrSWMaskHelper(SkAutoPixmapStorage* pixels = nullptr)
|
||||
: fPixels(pixels ? pixels : &fPixelsStorage) { }
|
||||
|
||||
// Make a texture by drawing a software mask. If the context has a task group, the draw will be
|
||||
// done async in that task group, and a lazy proxy will be returned to wait & upload it.
|
||||
// Otherwise the drawing is done immediately.
|
||||
// NOTE: The draw fn is async – it should not capture by reference.
|
||||
static GrSurfaceProxyView MakeTexture(SkIRect bounds,
|
||||
GrRecordingContext*,
|
||||
SkBackingFit,
|
||||
DrawFunc&&);
|
||||
// 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.
|
||||
bool init(const SkIRect& resultBounds);
|
||||
|
||||
// Draw a single rect into the accumulation bitmap using the specified op
|
||||
void drawRect(const SkRect& rect, const SkMatrix& matrix, SkRegion::Op op, GrAA, uint8_t alpha);
|
||||
@ -63,38 +57,24 @@ public:
|
||||
// Draw a single path into the accumuation bitmap using the specified op
|
||||
void drawShape(const GrStyledShape&, const SkMatrix& matrix, SkRegion::Op op, GrAA,
|
||||
uint8_t alpha);
|
||||
|
||||
// Like the GrStyledShape variant, but assumes a simple fill style
|
||||
void drawShape(const GrShape&, const SkMatrix& matrix, SkRegion::Op op, GrAA, uint8_t alpha);
|
||||
|
||||
GrSurfaceProxyView toTextureView(GrRecordingContext*, SkBackingFit fit);
|
||||
|
||||
// Reset the internal bitmap
|
||||
void clear(uint8_t alpha) {
|
||||
fBitmap.pixmap().erase(SkColorSetARGB(alpha, 0xFF, 0xFF, 0xFF));
|
||||
fPixels->erase(SkColorSetARGB(alpha, 0xFF, 0xFF, 0xFF));
|
||||
}
|
||||
|
||||
private:
|
||||
GrSWMaskHelper(const SkIRect& resultBounds);
|
||||
SkVector fTranslate;
|
||||
SkAutoPixmapStorage* fPixels;
|
||||
SkAutoPixmapStorage fPixelsStorage;
|
||||
SkDraw fDraw;
|
||||
SkRasterClip fRasterClip;
|
||||
|
||||
GrSWMaskHelper(const GrSWMaskHelper&) = delete;
|
||||
GrSWMaskHelper& operator=(const GrSWMaskHelper&) = delete;
|
||||
|
||||
GrSurfaceProxyView nonThreadedExecute(GrRecordingContext*,
|
||||
SkBackingFit,
|
||||
const DrawFunc&);
|
||||
|
||||
// `this` must be heap-allocated. Task & proxy take on ownership; do not unref.
|
||||
GrSurfaceProxyView threadedExecute(SkTaskGroup*,
|
||||
GrRecordingContext*,
|
||||
SkBackingFit,
|
||||
DrawFunc&&);
|
||||
|
||||
bool allocate();
|
||||
|
||||
SkVector fTranslate;
|
||||
SkBitmap fBitmap;
|
||||
SkDraw fDraw;
|
||||
SkRasterClip fRasterClip;
|
||||
SkSemaphore fSemaphore;
|
||||
using INHERITED = SkNoncopyable;
|
||||
};
|
||||
|
||||
#endif // GrSWMaskHelper_DEFINED
|
||||
|
@ -173,10 +173,27 @@ void GrSoftwarePathRenderer::DrawToTargetWithShapeMask(
|
||||
dstRect, invert);
|
||||
}
|
||||
|
||||
static GrSurfaceProxyView make_deferred_mask_texture_view(GrRecordingContext* context,
|
||||
SkBackingFit fit,
|
||||
SkISize dimensions) {
|
||||
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
|
||||
const GrCaps* caps = context->priv().caps();
|
||||
|
||||
const GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
|
||||
GrRenderable::kNo);
|
||||
|
||||
GrSwizzle swizzle = caps->getReadSwizzle(format, GrColorType::kAlpha_8);
|
||||
|
||||
auto proxy =
|
||||
proxyProvider->createProxy(format, dimensions, GrRenderable::kNo, 1, GrMipmapped::kNo,
|
||||
fit, SkBudgeted::kYes, GrProtected::kNo);
|
||||
return {std::move(proxy), kTopLeft_GrSurfaceOrigin, swizzle};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Payload class for use with GrSWMaskHelper. The software path renderer only draws
|
||||
* Payload class for use with GrTDeferredProxyUploader. The software path renderer only draws
|
||||
* a single path into the mask texture. This stores all of the information needed by the worker
|
||||
* thread's call to drawShape (see below, in onDrawPath).
|
||||
*/
|
||||
@ -190,7 +207,7 @@ public:
|
||||
, fAA(aa) {}
|
||||
|
||||
const SkIRect& getMaskBounds() const { return fMaskBounds; }
|
||||
const SkMatrix& getViewMatrix() const { return fViewMatrix; }
|
||||
const SkMatrix* getViewMatrix() const { return &fViewMatrix; }
|
||||
const GrStyledShape& getShape() const { return fShape; }
|
||||
GrAA getAA() const { return fAA; }
|
||||
|
||||
@ -309,15 +326,44 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
|
||||
if (!view) {
|
||||
SkBackingFit fit = useCache ? SkBackingFit::kExact : SkBackingFit::kApprox;
|
||||
GrAA aa = GrAA(GrAAType::kCoverage == args.fAAType);
|
||||
SoftwarePathData data(*boundsForMask, *args.fViewMatrix, *args.fShape, aa);
|
||||
view = GrSWMaskHelper::MakeTexture(data.getMaskBounds(),
|
||||
args.fContext,
|
||||
fit,
|
||||
[data{std::move(data)}](GrSWMaskHelper* helper) {
|
||||
TRACE_EVENT0("skia.gpu", "SW Mask Render");
|
||||
helper->drawShape(data.getShape(), data.getViewMatrix(), SkRegion::kReplace_Op,
|
||||
data.getAA(), 0xFF);
|
||||
});
|
||||
|
||||
SkTaskGroup* taskGroup = nullptr;
|
||||
if (auto direct = args.fContext->asDirectContext()) {
|
||||
taskGroup = direct->priv().getTaskGroup();
|
||||
}
|
||||
|
||||
if (taskGroup) {
|
||||
view = make_deferred_mask_texture_view(args.fContext, fit, boundsForMask->size());
|
||||
if (!view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto uploader = std::make_unique<GrTDeferredProxyUploader<SoftwarePathData>>(
|
||||
*boundsForMask, *args.fViewMatrix, *args.fShape, aa);
|
||||
GrTDeferredProxyUploader<SoftwarePathData>* uploaderRaw = uploader.get();
|
||||
|
||||
auto drawAndUploadMask = [uploaderRaw] {
|
||||
TRACE_EVENT0("skia.gpu", "Threaded SW Mask Render");
|
||||
GrSWMaskHelper helper(uploaderRaw->getPixels());
|
||||
if (helper.init(uploaderRaw->data().getMaskBounds())) {
|
||||
helper.drawShape(uploaderRaw->data().getShape(),
|
||||
*uploaderRaw->data().getViewMatrix(),
|
||||
SkRegion::kReplace_Op, uploaderRaw->data().getAA(), 0xFF);
|
||||
} else {
|
||||
SkDEBUGFAIL("Unable to allocate SW mask.");
|
||||
}
|
||||
uploaderRaw->signalAndFreeData();
|
||||
};
|
||||
taskGroup->add(std::move(drawAndUploadMask));
|
||||
view.asTextureProxy()->texPriv().setDeferredUploader(std::move(uploader));
|
||||
} else {
|
||||
GrSWMaskHelper helper;
|
||||
if (!helper.init(*boundsForMask)) {
|
||||
return false;
|
||||
}
|
||||
helper.drawShape(*args.fShape, *args.fViewMatrix, SkRegion::kReplace_Op, aa, 0xFF);
|
||||
view = helper.toTextureView(args.fContext, fit);
|
||||
}
|
||||
|
||||
if (!view) {
|
||||
return false;
|
||||
|
@ -1577,12 +1577,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ClipMaskCache, reporter, ctxInfo) {
|
||||
stack.clipPath(path, m, SkClipOp::kIntersect, true);
|
||||
sk_sp<GrTextureProxy> mask =
|
||||
GrClipStackClip(stackBounds.size(), &stack).testingOnly_createClipMask(context);
|
||||
// TODO: Make `instantiate` work for lazy proxies.
|
||||
if (mask->isLazy()) {
|
||||
mask->priv().doLazyInstantiation(context->priv().resourceProvider());
|
||||
} else {
|
||||
mask->instantiate(context->priv().resourceProvider());
|
||||
}
|
||||
mask->instantiate(context->priv().resourceProvider());
|
||||
GrTexture* tex = mask->peekTexture();
|
||||
REPORTER_ASSERT(reporter, 0 == strcmp(tex->getUniqueKey().tag(), kTag));
|
||||
// Make sure mask isn't pinned in cache.
|
||||
|
Loading…
Reference in New Issue
Block a user