diff options
author | reed <reed@google.com> | 2014-10-29 12:36:45 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-29 12:36:45 -0700 |
commit | 89889b69391a730f0ba2a1efb549864b7762263f (patch) | |
tree | 85e8cb00c41ae79cf4a693491138acd7853b0dfb | |
parent | 8f3937d9fcb28018ec14db6697d41b645716d589 (diff) |
MultiPictureDraw is taskgroup aware.
SampleApp is multipicturedraw aware.
BUG=skia:
Review URL: https://codereview.chromium.org/684923002
-rw-r--r-- | gyp/core.gypi | 2 | ||||
-rw-r--r-- | gyp/dm.gypi | 2 | ||||
-rwxr-xr-x | gyp/pathops_skpclip.gyp | 1 | ||||
-rw-r--r-- | gyp/pathops_unittest.gyp | 1 | ||||
-rw-r--r-- | gyp/tools.gyp | 1 | ||||
-rw-r--r-- | include/core/SkMultiPictureDraw.h | 20 | ||||
-rw-r--r-- | samplecode/SampleApp.cpp | 39 | ||||
-rw-r--r-- | src/core/SkMultiPictureDraw.cpp | 137 | ||||
-rw-r--r-- | src/core/SkTaskGroup.cpp (renamed from src/utils/SkTaskGroup.cpp) | 1 | ||||
-rw-r--r-- | src/core/SkTaskGroup.h (renamed from src/utils/SkTaskGroup.h) | 3 | ||||
-rw-r--r-- | tests/LazyPtrTest.cpp | 1 | ||||
-rw-r--r-- | tests/OnceTest.cpp | 1 | ||||
-rwxr-xr-x | tests/PathOpsSkpClipTest.cpp | 1 | ||||
-rw-r--r-- | tests/skia_test.cpp | 1 |
14 files changed, 146 insertions, 65 deletions
diff --git a/gyp/core.gypi b/gyp/core.gypi index 9170fabde5..39454b6539 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -188,6 +188,8 @@ '<(skia_src_path)/core/SkStrokeRec.cpp', '<(skia_src_path)/core/SkStrokerPriv.cpp', '<(skia_src_path)/core/SkStrokerPriv.h', + '<(skia_src_path)/core/SkTaskGroup.cpp', + '<(skia_src_path)/core/SkTaskGroup.h', '<(skia_src_path)/core/SkTextBlob.cpp', '<(skia_src_path)/core/SkTextFormatParams.h', '<(skia_src_path)/core/SkTextMapStateProc.h', diff --git a/gyp/dm.gypi b/gyp/dm.gypi index c7447153d2..932f430dad 100644 --- a/gyp/dm.gypi +++ b/gyp/dm.gypi @@ -45,8 +45,6 @@ '../dm/DMWriteTask.cpp', '../gm/gm.cpp', - '../src/utils/SkTaskGroup.cpp', - '../src/pipe/utils/SamplePipeControllers.cpp', '../src/utils/debugger/SkDebugCanvas.cpp', '../src/utils/debugger/SkDrawCommand.cpp', diff --git a/gyp/pathops_skpclip.gyp b/gyp/pathops_skpclip.gyp index 32a909bd47..4dadd7942e 100755 --- a/gyp/pathops_skpclip.gyp +++ b/gyp/pathops_skpclip.gyp @@ -24,7 +24,6 @@ 'sources': [ '../tests/PathOpsDebug.cpp', '../tests/PathOpsSkpClipTest.cpp', - '../src/utils/SkTaskGroup.cpp', ], 'conditions': [ [ 'skia_android_framework == 1', { diff --git a/gyp/pathops_unittest.gyp b/gyp/pathops_unittest.gyp index 1aaccfa25d..c8732545f2 100644 --- a/gyp/pathops_unittest.gyp +++ b/gyp/pathops_unittest.gyp @@ -21,7 +21,6 @@ '../tests/PathOpsDebug.cpp', '../tests/PathOpsOpLoopThreadedTest.cpp', '../tests/skia_test.cpp', - '../src/utils/SkTaskGroup.cpp', ], 'conditions': [ [ 'skia_android_framework == 1', { diff --git a/gyp/tools.gyp b/gyp/tools.gyp index e689ed1fd7..dae1cf58c7 100644 --- a/gyp/tools.gyp +++ b/gyp/tools.gyp @@ -165,7 +165,6 @@ '../tools/skpdiff/SkImageDiffer.cpp', '../tools/skpdiff/SkPMetric.cpp', '../tools/skpdiff/skpdiff_util.cpp', - '../src/utils/SkTaskGroup.cpp', ], 'include_dirs': [ '../src/core/', # needed for SkTLList.h diff --git a/include/core/SkMultiPictureDraw.h b/include/core/SkMultiPictureDraw.h index d8d9cb7ecd..461d38136b 100644 --- a/include/core/SkMultiPictureDraw.h +++ b/include/core/SkMultiPictureDraw.h @@ -56,13 +56,23 @@ public: private: struct DrawData { - SkCanvas* canvas; // reffed - const SkPicture* picture; // reffed - SkMatrix matrix; - SkPaint* paint; // owned + SkCanvas* fCanvas; // reffed + const SkPicture* fPicture; // reffed + SkMatrix fMatrix; + SkPaint* fPaint; // owned + + void init(SkCanvas*, const SkPicture*, const SkMatrix*, const SkPaint*); + void draw(); + + static void Reset(SkTDArray<DrawData>&); + + static void Run(void* ctx) { + static_cast<DrawData*>(ctx)->draw(); + } }; - SkTDArray<DrawData> fDrawData; + SkTDArray<DrawData> fThreadSafeDrawData; + SkTDArray<DrawData> fGPUDrawData; }; #endif diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 2c17379f88..1b4a55e5dd 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -742,6 +742,8 @@ DEFINE_bool(list, false, "List samples?"); DEFINE_string(pdfPath, "", "Path to direcotry of pdf files."); #endif +#include "SkTaskGroup.h" + SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* devManager) : INHERITED(hwnd) , fDevManager(NULL) { @@ -813,6 +815,7 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev fCurrIndex = 0; } + static SkTaskGroup::Enabler enabled(-1); gSampleWindow = this; #ifdef PIPE_FILE @@ -1306,7 +1309,7 @@ SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) { return canvas; } - +#include "SkMultiPictureDraw.h" void SampleWindow::afterChildren(SkCanvas* orig) { if (fSaveToPdf) { fSaveToPdf = false; @@ -1336,7 +1339,39 @@ void SampleWindow::afterChildren(SkCanvas* orig) { if (true) { this->installDrawFilter(orig); - orig->drawPicture(picture); + + if (true) { + SkImageInfo info; + size_t rowBytes; + void* addr = orig->accessTopLayerPixels(&info, &rowBytes); + if (addr) { + SkSurface* surfs[4]; + SkMultiPictureDraw md; + + SkImageInfo n = SkImageInfo::Make(info.width()/2, info.height()/2, + info.colorType(), info.alphaType()); + int index = 0; + for (int y = 0; y < 2; ++y) { + for (int x = 0; x < 2; ++x) { + char* p = (char*)addr; + p += y * n.height() * rowBytes; + p += x * n.width() * sizeof(SkPMColor); + surfs[index] = SkSurface::NewRasterDirect(n, p, rowBytes); + SkCanvas* c = surfs[index]->getCanvas(); + c->translate(SkIntToScalar(-x * n.width()), + SkIntToScalar(-y * n.height())); + md.add(c, picture, NULL, NULL); + index++; + } + } + md.draw(); + for (int i = 0; i < 4; ++i) { + surfs[i]->unref(); + } + } + } else { + orig->drawPicture(picture); + } } else if (true) { SkDynamicMemoryWStream ostream; picture->serialize(&ostream); diff --git a/src/core/SkMultiPictureDraw.cpp b/src/core/SkMultiPictureDraw.cpp index 5fe3c0ea52..b59b63bffc 100644 --- a/src/core/SkMultiPictureDraw.cpp +++ b/src/core/SkMultiPictureDraw.cpp @@ -13,21 +13,49 @@ #include "SkCanvas.h" #include "SkMultiPictureDraw.h" #include "SkPicture.h" +#include "SkTaskGroup.h" + +void SkMultiPictureDraw::DrawData::draw() { + fCanvas->drawPicture(fPicture, &fMatrix, fPaint); +} + +void SkMultiPictureDraw::DrawData::init(SkCanvas* canvas, const SkPicture* picture, + const SkMatrix* matrix, const SkPaint* paint) { + fPicture = SkRef(picture); + fCanvas = SkRef(canvas); + if (matrix) { + fMatrix = *matrix; + } else { + fMatrix.setIdentity(); + } + if (paint) { + fPaint = SkNEW_ARGS(SkPaint, (*paint)); + } else { + fPaint = NULL; + } +} + +void SkMultiPictureDraw::DrawData::Reset(SkTDArray<DrawData>& data) { + for (int i = 0; i < data.count(); ++i) { + data[i].fPicture->unref(); + data[i].fCanvas->unref(); + SkDELETE(data[i].fPaint); + } + data.rewind(); +} + +////////////////////////////////////////////////////////////////////////////////////// SkMultiPictureDraw::SkMultiPictureDraw(int reserve) { if (reserve > 0) { - fDrawData.setReserve(reserve); + fGPUDrawData.setReserve(reserve); + fThreadSafeDrawData.setReserve(reserve); } } void SkMultiPictureDraw::reset() { - for (int i = 0; i < fDrawData.count(); ++i) { - fDrawData[i].picture->unref(); - fDrawData[i].canvas->unref(); - SkDELETE(fDrawData[i].paint); - } - - fDrawData.rewind(); + DrawData::Reset(fGPUDrawData); + DrawData::Reset(fThreadSafeDrawData); } void SkMultiPictureDraw::add(SkCanvas* canvas, @@ -39,47 +67,58 @@ void SkMultiPictureDraw::add(SkCanvas* canvas, return; } - DrawData* data = fDrawData.append(); - - data->picture = SkRef(picture); - data->canvas = SkRef(canvas); - if (matrix) { - data->matrix = *matrix; - } else { - data->matrix.setIdentity(); - } - if (paint) { - data->paint = SkNEW_ARGS(SkPaint, (*paint)); - } else { - data->paint = NULL; - } + SkTDArray<DrawData>& array = canvas->getGrContext() ? fGPUDrawData : fThreadSafeDrawData; + array.append()->init(canvas, picture, matrix, paint); } #undef SK_IGNORE_GPU_LAYER_HOISTING #define SK_IGNORE_GPU_LAYER_HOISTING 1 +class AutoMPDReset : SkNoncopyable { + SkMultiPictureDraw* fMPD; +public: + AutoMPDReset(SkMultiPictureDraw* mpd) : fMPD(mpd) {} + ~AutoMPDReset() { fMPD->reset(); } +}; + void SkMultiPictureDraw::draw() { + AutoMPDReset mpdreset(this); + // we place the taskgroup after the MPDReset, to ensure that we don't delete the DrawData + // objects until after we're finished the tasks (which have pointers to the data). + + SkTaskGroup group; + for (int i = 0; i < fThreadSafeDrawData.count(); ++i) { + group.add(DrawData::Run, &fThreadSafeDrawData[i]); + } + // we deliberately don't call wait() here, since the destructor will do that, this allows us + // to continue processing gpu-data without having to wait on the cpu tasks. + + const int count = fGPUDrawData.count(); + if (0 == count) { + return; + } #ifndef SK_IGNORE_GPU_LAYER_HOISTING - GrContext* context = NULL; + GrContext* context = fGPUDrawData[0].fCanvas->getGrContext(); + SkASSERT(context); - // Start by collecting all the layers that are going to be atlased and render + // Start by collecting all the layers that are going to be atlased and render // them (if necessary). Hoisting the free floating layers is deferred until // drawing the canvas that requires them. SkTDArray<GrHoistedLayer> atlasedNeedRendering, atlasedRecycled; - for (int i = 0; i < fDrawData.count(); ++i) { - if (fDrawData[i].canvas->getGrContext() && - !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { - SkASSERT(NULL == context || context == fDrawData[i].canvas->getGrContext()); - context = fDrawData[i].canvas->getGrContext(); + for (int i = 0; i < count; ++i) { + const DrawData& data = fGPUDrawData[i]; + // we only expect 1 context for all the canvases + SkASSERT(data.canvas->getGrContext() == context); + if (!data.fPaint && data.fMatrix.isIdentity()) { // TODO: this path always tries to optimize pictures. Should we // switch to this API approach (vs. SkCanvas::EXPERIMENTAL_optimize)? - fDrawData[i].canvas->EXPERIMENTAL_optimize(fDrawData[i].picture); + data.fCanvas->EXPERIMENTAL_optimize(data.fPicture); SkRect clipBounds; - if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { + if (!data.fCanvas->getClipBounds(&clipBounds)) { continue; } @@ -87,32 +126,33 @@ void SkMultiPictureDraw::draw() { // would improve the packing and reduce the number of swaps // TODO: another optimization would be to make a first pass to // lock any required layer that is already in the atlas - GrLayerHoister::FindLayersToAtlas(context, fDrawData[i].picture, + GrLayerHoister::FindLayersToAtlas(context, data.fPicture, clipBounds, &atlasedNeedRendering, &atlasedRecycled); } } - if (NULL != context) { - GrLayerHoister::DrawLayersToAtlas(context, atlasedNeedRendering); - } + GrLayerHoister::DrawLayersToAtlas(context, atlasedNeedRendering); SkTDArray<GrHoistedLayer> needRendering, recycled; #endif - for (int i = 0; i < fDrawData.count(); ++i) { + for (int i = 0; i < count; ++i) { + const DrawData& data = fGPUDrawData[i]; + SkCanvas* canvas = data.fCanvas; + const SkPicture* picture = data.fPicture; + #ifndef SK_IGNORE_GPU_LAYER_HOISTING - if (fDrawData[i].canvas->getGrContext() && - !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { + if (!data.fPaint && data.fMatrix.isIdentity()) { SkRect clipBounds; - if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { + if (!canvas->getClipBounds(&clipBounds)) { continue; } // Find the layers required by this canvas. It will return atlased // layers in the 'recycled' list since they have already been drawn. - GrLayerHoister::FindLayersToHoist(context, fDrawData[i].picture, + GrLayerHoister::FindLayersToHoist(context, picture, clipBounds, &needRendering, &recycled); GrLayerHoister::DrawLayers(context, needRendering); @@ -122,11 +162,10 @@ void SkMultiPictureDraw::draw() { GrLayerHoister::ConvertLayersToReplacements(needRendering, &replacements); GrLayerHoister::ConvertLayersToReplacements(recycled, &replacements); - const SkMatrix initialMatrix = fDrawData[i].canvas->getTotalMatrix(); + const SkMatrix initialMatrix = canvas->getTotalMatrix(); // Render the entire picture using new layers - GrRecordReplaceDraw(fDrawData[i].picture, fDrawData[i].canvas, - &replacements, initialMatrix, NULL); + GrRecordReplaceDraw(picture, canvas, &replacements, initialMatrix, NULL); GrLayerHoister::UnlockLayers(context, needRendering); GrLayerHoister::UnlockLayers(context, recycled); @@ -136,19 +175,13 @@ void SkMultiPictureDraw::draw() { } else #endif { - fDrawData[i].canvas->drawPicture(fDrawData[i].picture, - &fDrawData[i].matrix, - fDrawData[i].paint); + canvas->drawPicture(picture, &data.fMatrix, data.fPaint); } } #ifndef SK_IGNORE_GPU_LAYER_HOISTING - if (NULL != context) { - GrLayerHoister::UnlockLayers(context, atlasedNeedRendering); - GrLayerHoister::UnlockLayers(context, atlasedRecycled); - } + GrLayerHoister::UnlockLayers(context, atlasedNeedRendering); + GrLayerHoister::UnlockLayers(context, atlasedRecycled); #endif - - this->reset(); } diff --git a/src/utils/SkTaskGroup.cpp b/src/core/SkTaskGroup.cpp index f1ec7f4278..dd12538743 100644 --- a/src/utils/SkTaskGroup.cpp +++ b/src/core/SkTaskGroup.cpp @@ -1,6 +1,7 @@ #include "SkTaskGroup.h" #include "SkCondVar.h" +#include "SkRunnable.h" #include "SkTDArray.h" #include "SkThread.h" #include "SkThreadUtils.h" diff --git a/src/utils/SkTaskGroup.h b/src/core/SkTaskGroup.h index c60ceda52e..75443c37cb 100644 --- a/src/utils/SkTaskGroup.h +++ b/src/core/SkTaskGroup.h @@ -9,7 +9,8 @@ #define SkTaskGroup_DEFINED #include "SkTypes.h" -#include "SkRunnable.h" + +struct SkRunnable; class SkTaskGroup : SkNoncopyable { public: diff --git a/tests/LazyPtrTest.cpp b/tests/LazyPtrTest.cpp index f719c2e0bf..799f705085 100644 --- a/tests/LazyPtrTest.cpp +++ b/tests/LazyPtrTest.cpp @@ -1,5 +1,6 @@ #include "Test.h" #include "SkLazyPtr.h" +#include "SkRunnable.h" #include "SkTaskGroup.h" namespace { diff --git a/tests/OnceTest.cpp b/tests/OnceTest.cpp index e2711f00bb..da901f41c4 100644 --- a/tests/OnceTest.cpp +++ b/tests/OnceTest.cpp @@ -6,6 +6,7 @@ */ #include "SkOnce.h" +#include "SkRunnable.h" #include "SkTaskGroup.h" #include "Test.h" diff --git a/tests/PathOpsSkpClipTest.cpp b/tests/PathOpsSkpClipTest.cpp index b8142cd654..ad0a95f22b 100755 --- a/tests/PathOpsSkpClipTest.cpp +++ b/tests/PathOpsSkpClipTest.cpp @@ -15,6 +15,7 @@ #include "SkPathOpsDebug.h" #include "SkPicture.h" #include "SkRTConf.h" +#include "SkRunnable.h" #include "SkTSort.h" #include "SkStream.h" #include "SkString.h" diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp index 0058215ccf..172328ee4a 100644 --- a/tests/skia_test.cpp +++ b/tests/skia_test.cpp @@ -11,6 +11,7 @@ #include "SkCommonFlags.h" #include "SkGraphics.h" #include "SkOSFile.h" +#include "SkRunnable.h" #include "SkTArray.h" #include "SkTaskGroup.h" #include "SkTemplates.h" |