Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Unified Diff: src/gpu/SkGpuDevice.cpp

Issue 474623002: Add new API to allow layer hoisting/atlasing across picture piles Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: more cleanup Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/gpu/gl/GrGpuGL.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/SkGpuDevice.cpp
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 693e16c0e320d13ad9889320f947c7b9f11ed8bf..3b2e5b17d78407bc55eeddde4070c72c8eb79f48 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1887,7 +1887,7 @@ bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData,
// reused with different clips (e.g., in different tiles). Because of this the
// clip will not be limiting the size of the pre-rendered layer. kSaveLayerMaxSize
// is used to limit which clips are pre-rendered.
- static const int kSaveLayerMaxSize = 256;
+ static const int kSaveLayerMaxSize1 = 512;
if (NULL != ops) {
// In this case the picture has been generated with a BBH so we use
@@ -1913,8 +1913,9 @@ bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData,
// TODO: once this code is more stable unsuitable layers can
// just be omitted during the optimization stage
if (!info.fValid ||
- kSaveLayerMaxSize < info.fSize.fWidth ||
- kSaveLayerMaxSize < info.fSize.fHeight ||
+ kSaveLayerMaxSize1 < info.fSize.fWidth ||
+ kSaveLayerMaxSize1 < info.fSize.fHeight ||
+ info.fSize.fWidth * info.fSize.fHeight > 256 * 256 ||
info.fIsNested) {
continue; // this layer is unsuitable
}
@@ -1941,8 +1942,9 @@ bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData,
// TODO: once this code is more stable unsuitable layers can
// just be omitted during the optimization stage
if (!info.fValid ||
- kSaveLayerMaxSize < info.fSize.fWidth ||
- kSaveLayerMaxSize < info.fSize.fHeight ||
+ kSaveLayerMaxSize1 < info.fSize.fWidth ||
+ kSaveLayerMaxSize1 < info.fSize.fHeight ||
+ info.fSize.fWidth * info.fSize.fHeight > 256 * 256 ||
info.fIsNested) {
continue;
}
@@ -1957,8 +1959,7 @@ bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData,
bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* picture,
const SkMatrix* matrix, const SkPaint* paint) {
- // todo: should handle these natively
- if (matrix || paint) {
+ if (NULL != matrix || NULL != paint) {
return false;
}
@@ -1996,62 +1997,97 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
}
SkPictureReplacementPlayback::PlaybackReplacements replacements;
+}
+
+void SkGpuDevice::EXPERIMENTAL_preDrawPicture(const SkPicture* picture,
+ const SkMatrix* matrix, const SkPaint* paint,
+ const SkIRect* target) {
+ if (NULL != matrix || NULL != paint) {
+ return;
+ }
- SkTDArray<GrCachedLayer*> atlased, nonAtlased;
- atlased.setReserve(gpuData->numSaveLayers());
+ fContext->getLayerCache()->processDeletedPictures();
- // Generate the layer and/or ensure it is locked
+ SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
+
+ const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key);
+ if (NULL == data) {
+ return;
+ }
+
+ const GrAccelData *gpuData = static_cast<const GrAccelData*>(data);
+
+ if (0 == gpuData->numSaveLayers()) {
+ return;
+ }
+
+ SkAutoTArray<bool> pullForward(gpuData->numSaveLayers());
for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
- if (pullForward[i]) {
- const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
+ pullForward[i] = false;
+ }
- GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(),
- info.fSaveLayerOpID,
- info.fRestoreOpID,
- info.fCTM);
-
- SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
- replacements.push();
- layerInfo->fStart = info.fSaveLayerOpID;
- layerInfo->fStop = info.fRestoreOpID;
- layerInfo->fPos = info.fOffset;
-
- GrTextureDesc desc;
- desc.fFlags = kRenderTarget_GrTextureFlagBit;
- desc.fWidth = info.fSize.fWidth;
- desc.fHeight = info.fSize.fHeight;
- desc.fConfig = kSkia8888_GrPixelConfig;
- // TODO: need to deal with sample count
-
- bool needsRendering = fContext->getLayerCache()->lock(layer, desc,
- info.fHasNestedLayers || info.fIsNested);
- if (NULL == layer->texture()) {
- continue;
- }
+ SkAutoTDelete<const SkPicture::OperationList> ops;
+ SkIRect query;
+
+ if (NULL != target) {
+ // TODO: this is suboptimal since it will be repeated in EXPERIMENTAL_drawPicture!
+ // TODO: just always use 'target' to determine hoisting (rather than active ops)?
+ ops.reset(picture->EXPERIMENTAL_getActiveOps(*target));
+ query = *target;
+ } else {
+ query = SkIRect::MakeWH(picture->width(), picture->height());
+ }
- layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD
- wrap_texture(layer->texture(),
- !layer->isAtlased() ? desc.fWidth : layer->texture()->width(),
- !layer->isAtlased() ? desc.fHeight : layer->texture()->height(),
- layerInfo->fBM);
+ if (!FindLayersToHoist(gpuData, ops.get(), query, pullForward.get())) {
+ return;
+ }
- SkASSERT(info.fPaint);
- layerInfo->fPaint = info.fPaint;
+ *fPreprocessed.append() = SkRef(picture);
- layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft,
- layer->rect().fTop,
- layer->rect().width(),
- layer->rect().height());
+ fDeferredAtlasDraws.setReserve(fDeferredAtlasDraws.count() + gpuData->numSaveLayers());
- if (needsRendering) {
- if (layer->isAtlased()) {
- *atlased.append() = layer;
- } else {
- *nonAtlased.append() = layer;
- }
+ // Lock the memory required for all the hoisted layers and add them
+ // to the deferred drawing lists
+ // TODO: this may be a bit more VRAM intensive then necessary
+ for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
+ if (!pullForward[i]) {
+ continue;
+ }
+
+ const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
+
+ GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(),
+ info.fSaveLayerOpID,
+ info.fRestoreOpID,
+ info.fCTM);
+
+ GrTextureDesc desc;
+ desc.fFlags = kRenderTarget_GrTextureFlagBit;
+ desc.fWidth = info.fSize.fWidth;
+ desc.fHeight = info.fSize.fHeight;
+ desc.fConfig = kSkia8888_GrPixelConfig;
+ // TODO: need to deal with sample count
+
+ bool needsRendering = fContext->getLayerCache()->lock(layer, desc,
+ info.fHasNestedLayers || info.fIsNested);
+ if (NULL == layer->texture()) {
+ continue;
+ }
+
+ if (needsRendering) {
+ DeferredDraw* draw;
+
+ if (layer->isAtlased()) {
+ draw = fDeferredAtlasDraws.append();
+ } else {
+ draw = fDeferredNonAtlasDraws.append();
}
+
+ draw->layer = layer;
+ draw->picture1 = picture;
}
}
+}
this->drawLayers(picture, atlased, nonAtlased);
@@ -2150,6 +2186,7 @@ void SkGpuDevice::drawLayers(const SkPicture* picture,
}
}
+<<<<<<< HEAD
void SkGpuDevice::unlockLayers(const SkPicture* picture) {
SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
@@ -2158,26 +2195,147 @@ void SkGpuDevice::unlockLayers(const SkPicture* picture) {
const GrAccelData *gpuData = static_cast<const GrAccelData*>(data);
SkASSERT(0 != gpuData->numSaveLayers());
+=======
+ fDeferredAtlasDraws.rewind();
+ fDeferredNonAtlasDraws.rewind();
+}
+
+bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* picture,
+ const SkMatrix* matrix, const SkPaint* paint) {
+ // todo: should handle these natively
+ if (matrix || paint) {
+ return false;
+ }
+
+ fContext->getLayerCache()->processDeletedPictures();
+
+ SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
- // unlock the layers
+ const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key);
+ if (NULL == data) {
+ return false;
+ }
+
+ const GrAccelData *gpuData = static_cast<const GrAccelData*>(data);
+
+ if (0 == gpuData->numSaveLayers()) {
+ return false;
+ }
+
+ SkAutoTArray<bool> pullForward(gpuData->numSaveLayers());
+ for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
+ pullForward[i] = false;
+ }
+
+ SkRect clipBounds;
+ if (!mainCanvas->getClipBounds(&clipBounds)) {
+ return true;
+ }
+ SkIRect query;
+ clipBounds.roundOut(&query);
+
+ SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getActiveOps(query));
+>>>>>>> Reapply patch
+
+ if (!FindLayersToHoist(gpuData, ops.get(), query, pullForward.get())) {
+ return false;
+ }
+
+ this->flushDeferredDraws();
+
+ SkPictureReplacementPlayback::PlaybackReplacements replacements;
+
+ // Assemble the information needed to render the original picture with the
+ // hoisted layers
for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
+ if (!pullForward[i]) {
+ continue;
+ }
+
const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
+<<<<<<< HEAD
GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture->uniqueID(),
info.fSaveLayerOpID,
info.fRestoreOpID,
info.fCTM);
fContext->getLayerCache()->unlock(layer);
+=======
+ GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(),
+ info.fSaveLayerOpID,
+ info.fRestoreOpID,
+ info.fCTM);
+ SkASSERT(layer->locked());
+
+ SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
+ replacements.push();
+ layerInfo->fStart = info.fSaveLayerOpID;
+ layerInfo->fStop = info.fRestoreOpID;
+ layerInfo->fPos = info.fOffset;
+
+ layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD
+ wrap_texture(layer->texture(),
+ layer->isAtlased() ? layer->texture()->width() : info.fSize.fWidth,
+ layer->isAtlased() ? layer->texture()->height() : info.fSize.fHeight,
+ layerInfo->fBM);
+
+ SkASSERT(info.fPaint);
+ layerInfo->fPaint = info.fPaint;
+
+ layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft,
+ layer->rect().fTop,
+ layer->rect().width(),
+ layer->rect().height());
+>>>>>>> Reapply patch
+ }
+
+ // Render the entire picture using new layers
+ SkPictureReplacementPlayback playback(picture, &replacements, ops.get());
+
+ playback.draw(mainCanvas, NULL);
+
+ return true;
+}
+
+void SkGpuDevice::EXPERIMENTAL_postDrawPicture() {
+ SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
+
+ for (int i = 0; i < fPreprocessed.count(); ++i) {
+ const SkPicture* picture = fPreprocessed[i];
+
+ const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key);
+ SkASSERT(NULL != data);
+
+ const GrAccelData *gpuData = static_cast<const GrAccelData*>(data);
+ SkASSERT(0 != gpuData->numSaveLayers());
+
+ // unlock the layers associated with the current picture
+ for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
+ const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
+
+ GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture->uniqueID(),
+ info.fSaveLayerOpID,
+ info.fRestoreOpID,
+ info.fCTM);
+ fContext->getLayerCache()->unlock(layer);
+ }
+
+#if DISABLE_CACHING
+ // TODO: for debugging only
+ fContext->getLayerCache()->purge(picture->uniqueID());
+#endif
+
+ picture->unref();
}
#if DISABLE_CACHING
// This code completely clears out the atlas. It is required when
// caching is disabled so the atlas doesn't fill up and force more
// free floating layers
- fContext->getLayerCache()->purge(picture->uniqueID());
-
fContext->getLayerCache()->purgeAll();
#endif
+
+ fPreprocessed.rewind();
}
SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
« no previous file with comments | « no previous file | src/gpu/gl/GrGpuGL.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698