aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2014-10-29 12:36:45 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-10-29 12:36:45 -0700
commit89889b69391a730f0ba2a1efb549864b7762263f (patch)
tree85e8cb00c41ae79cf4a693491138acd7853b0dfb
parent8f3937d9fcb28018ec14db6697d41b645716d589 (diff)
MultiPictureDraw is taskgroup aware.
SampleApp is multipicturedraw aware. BUG=skia: Review URL: https://codereview.chromium.org/684923002
-rw-r--r--gyp/core.gypi2
-rw-r--r--gyp/dm.gypi2
-rwxr-xr-xgyp/pathops_skpclip.gyp1
-rw-r--r--gyp/pathops_unittest.gyp1
-rw-r--r--gyp/tools.gyp1
-rw-r--r--include/core/SkMultiPictureDraw.h20
-rw-r--r--samplecode/SampleApp.cpp39
-rw-r--r--src/core/SkMultiPictureDraw.cpp137
-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.cpp1
-rw-r--r--tests/OnceTest.cpp1
-rwxr-xr-xtests/PathOpsSkpClipTest.cpp1
-rw-r--r--tests/skia_test.cpp1
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"