Enable DAA in the init-once phase of threaded backends
Bug: skia: Change-Id: Idb856fe12f0f9fa1014e7d15ef40bd7b456634d6 Reviewed-on: https://skia-review.googlesource.com/107540 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Yuqian Li <liyuqian@google.com>
This commit is contained in:
parent
9fd8eb6fec
commit
aefcccb5d8
@ -92,7 +92,11 @@ void SkBlitter::blitCoverageDeltas(SkCoverageDeltaList* deltas, const SkIRect& c
|
|||||||
bool canUseMask = !deltas->forceRLE() &&
|
bool canUseMask = !deltas->forceRLE() &&
|
||||||
SkCoverageDeltaMask::CanHandle(SkIRect::MakeLTRB(0, 0, clip.width(), 1));
|
SkCoverageDeltaMask::CanHandle(SkIRect::MakeLTRB(0, 0, clip.width(), 1));
|
||||||
const SkAntiRect& antiRect = deltas->getAntiRect();
|
const SkAntiRect& antiRect = deltas->getAntiRect();
|
||||||
for(int y = deltas->top(); y < deltas->bottom(); ++y) {
|
|
||||||
|
// Only access rows within our clip. Otherwise, we'll have data race in the threaded backend.
|
||||||
|
int top = SkTMax(deltas->top(), clip.fTop);
|
||||||
|
int bottom = SkTMin(deltas->bottom(), clip.fBottom);
|
||||||
|
for(int y = top; y < bottom; ++y) {
|
||||||
// If antiRect is non-empty and we're at its top row, blit it and skip to the bottom
|
// If antiRect is non-empty and we're at its top row, blit it and skip to the bottom
|
||||||
if (antiRect.fHeight && y == antiRect.fY) {
|
if (antiRect.fHeight && y == antiRect.fY) {
|
||||||
this->blitAntiRect(antiRect.fX, antiRect.fY, antiRect.fWidth, antiRect.fHeight,
|
this->blitAntiRect(antiRect.fX, antiRect.fY, antiRect.fWidth, antiRect.fHeight,
|
||||||
|
@ -1019,7 +1019,7 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
|
|||||||
|
|
||||||
if (iData == nullptr) {
|
if (iData == nullptr) {
|
||||||
proc(devPath, *fRC, blitter); // proceed directly if we're not in threaded init-once
|
proc(devPath, *fRC, blitter); // proceed directly if we're not in threaded init-once
|
||||||
} else if (true || !doFill || !paint.isAntiAlias()) {
|
} else if (!doFill || !paint.isAntiAlias()) {
|
||||||
// TODO remove true in the if statement above so we can proceed to DAA.
|
// TODO remove true in the if statement above so we can proceed to DAA.
|
||||||
|
|
||||||
// We're in threaded init-once but we can't use DAA. Hence we'll stop here and hand all the
|
// We're in threaded init-once but we can't use DAA. Hence we'll stop here and hand all the
|
||||||
@ -1033,7 +1033,15 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// We can use DAA to do scan conversion in the init-once phase.
|
// We can use DAA to do scan conversion in the init-once phase.
|
||||||
// TODO To be implemented
|
SkDAARecord* record = iData->fAlloc->make<SkDAARecord>(iData->fAlloc);
|
||||||
|
SkNullBlitter nullBlitter; // We don't want to blit anything during the init phase
|
||||||
|
SkScan::AntiFillPath(devPath, *fRC, &nullBlitter, record);
|
||||||
|
iData->fElement->setDrawFn([record, devPath, blitter](SkArenaAlloc* alloc,
|
||||||
|
const SkThreadedBMPDevice::DrawState& ds, const SkIRect& tileBounds) {
|
||||||
|
SkASSERT(record->fType != SkDAARecord::Type::kToBeComputed);
|
||||||
|
SkThreadedBMPDevice::TileDraw tileDraw(ds, tileBounds);
|
||||||
|
SkScan::AntiFillPath(devPath, *tileDraw.fRC, blitter, record);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ void SkThreadedBMPDevice::drawPath(const SkPath& path, const SkPaint& paint,
|
|||||||
const SkMatrix* prePathMatrix, bool pathIsMutable) {
|
const SkMatrix* prePathMatrix, bool pathIsMutable) {
|
||||||
SkRect drawBounds = path.isInverseFillType() ? SkRectPriv::MakeLargest()
|
SkRect drawBounds = path.isInverseFillType() ? SkRectPriv::MakeLargest()
|
||||||
: get_fast_bounds(path.getBounds(), paint);
|
: get_fast_bounds(path.getBounds(), paint);
|
||||||
if (path.countVerbs() < 100) { // when path is small, init-once has too much overhead
|
if (path.countVerbs() < 4) { // when path is small, init-once has too much overhead
|
||||||
fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, const SkIRect& tileBounds) {
|
fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, const SkIRect& tileBounds) {
|
||||||
TileDraw(ds, tileBounds).drawPath(path, paint, prePathMatrix, false);
|
TileDraw(ds, tileBounds).drawPath(path, paint, prePathMatrix, false);
|
||||||
});
|
});
|
||||||
|
@ -74,19 +74,26 @@ private:
|
|||||||
, fDrawBounds(device->transformDrawBounds(rawDrawBounds)) {}
|
, fDrawBounds(device->transformDrawBounds(rawDrawBounds)) {}
|
||||||
DrawElement(SkThreadedBMPDevice* device, InitFn&& initFn, const SkRect& rawDrawBounds)
|
DrawElement(SkThreadedBMPDevice* device, InitFn&& initFn, const SkRect& rawDrawBounds)
|
||||||
: fInitialized(false)
|
: fInitialized(false)
|
||||||
|
, fNeedInit(true)
|
||||||
, fInitFn(std::move(initFn))
|
, fInitFn(std::move(initFn))
|
||||||
, fDS(device)
|
, fDS(device)
|
||||||
, fDrawBounds(device->transformDrawBounds(rawDrawBounds)) {}
|
, fDrawBounds(device->transformDrawBounds(rawDrawBounds)) {}
|
||||||
|
|
||||||
SK_ALWAYS_INLINE bool tryInitOnce(SkArenaAlloc* alloc) {
|
SK_ALWAYS_INLINE bool tryInitOnce(SkArenaAlloc* alloc) {
|
||||||
if (fInitialized) {
|
bool t = true;
|
||||||
return false;
|
// If there are multiple threads reaching this point simutaneously,
|
||||||
}
|
// compare_exchange_strong ensures that only one thread can enter the if condition and
|
||||||
std::call_once(fNeedInit, [this, alloc]{
|
// do the initialization.
|
||||||
|
if (!fInitialized && fNeedInit && fNeedInit.compare_exchange_strong(t, false)) {
|
||||||
|
#ifdef SK_DEBUG
|
||||||
|
fDrawFn = 0; // Invalidate fDrawFn
|
||||||
|
#endif
|
||||||
fInitFn(alloc, this);
|
fInitFn(alloc, this);
|
||||||
fInitialized = true;
|
fInitialized = true;
|
||||||
});
|
SkASSERT(fDrawFn != 0); // Ensure that fInitFn does populate fDrawFn
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SK_ALWAYS_INLINE bool tryDraw(const SkIRect& tileBounds, SkArenaAlloc* alloc) {
|
SK_ALWAYS_INLINE bool tryDraw(const SkIRect& tileBounds, SkArenaAlloc* alloc) {
|
||||||
@ -105,7 +112,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<bool> fInitialized;
|
std::atomic<bool> fInitialized;
|
||||||
std::once_flag fNeedInit;
|
std::atomic<bool> fNeedInit;
|
||||||
InitFn fInitFn;
|
InitFn fInitFn;
|
||||||
DrawFn fDrawFn;
|
DrawFn fDrawFn;
|
||||||
DrawState fDS;
|
DrawState fDS;
|
||||||
|
Loading…
Reference in New Issue
Block a user