2014-08-21 20:12:42 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "SkCanvas.h"
|
2014-11-24 17:49:17 +00:00
|
|
|
#include "SkCanvasPriv.h"
|
2014-08-21 20:12:42 +00:00
|
|
|
#include "SkMultiPictureDraw.h"
|
|
|
|
#include "SkPicture.h"
|
2014-10-29 19:36:45 +00:00
|
|
|
#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);
|
2016-11-12 14:06:55 +00:00
|
|
|
fCanvas = canvas;
|
2014-10-29 19:36:45 +00:00
|
|
|
if (matrix) {
|
|
|
|
fMatrix = *matrix;
|
|
|
|
} else {
|
|
|
|
fMatrix.setIdentity();
|
|
|
|
}
|
|
|
|
if (paint) {
|
2015-08-26 20:07:48 +00:00
|
|
|
fPaint = new SkPaint(*paint);
|
2014-10-29 19:36:45 +00:00
|
|
|
} else {
|
2015-08-27 14:41:13 +00:00
|
|
|
fPaint = nullptr;
|
2014-10-29 19:36:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkMultiPictureDraw::DrawData::Reset(SkTDArray<DrawData>& data) {
|
|
|
|
for (int i = 0; i < data.count(); ++i) {
|
|
|
|
data[i].fPicture->unref();
|
2015-08-26 20:07:48 +00:00
|
|
|
delete data[i].fPaint;
|
2014-10-29 19:36:45 +00:00
|
|
|
}
|
|
|
|
data.rewind();
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
2014-08-21 20:12:42 +00:00
|
|
|
|
|
|
|
SkMultiPictureDraw::SkMultiPictureDraw(int reserve) {
|
|
|
|
if (reserve > 0) {
|
2014-10-29 19:36:45 +00:00
|
|
|
fGPUDrawData.setReserve(reserve);
|
|
|
|
fThreadSafeDrawData.setReserve(reserve);
|
2014-08-21 20:12:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkMultiPictureDraw::reset() {
|
2014-10-29 19:36:45 +00:00
|
|
|
DrawData::Reset(fGPUDrawData);
|
|
|
|
DrawData::Reset(fThreadSafeDrawData);
|
2014-08-21 20:12:42 +00:00
|
|
|
}
|
|
|
|
|
2014-10-29 21:17:13 +00:00
|
|
|
void SkMultiPictureDraw::add(SkCanvas* canvas,
|
2014-08-21 20:12:42 +00:00
|
|
|
const SkPicture* picture,
|
2014-10-29 21:17:13 +00:00
|
|
|
const SkMatrix* matrix,
|
2014-08-21 20:12:42 +00:00
|
|
|
const SkPaint* paint) {
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == canvas || nullptr == picture) {
|
|
|
|
SkDEBUGFAIL("parameters to SkMultiPictureDraw::add should be non-nullptr");
|
2014-08-21 20:12:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-29 19:36:45 +00:00
|
|
|
SkTDArray<DrawData>& array = canvas->getGrContext() ? fGPUDrawData : fThreadSafeDrawData;
|
|
|
|
array.append()->init(canvas, picture, matrix, paint);
|
2014-08-21 20:12:42 +00:00
|
|
|
}
|
|
|
|
|
2014-10-29 19:36:45 +00:00
|
|
|
class AutoMPDReset : SkNoncopyable {
|
|
|
|
SkMultiPictureDraw* fMPD;
|
|
|
|
public:
|
|
|
|
AutoMPDReset(SkMultiPictureDraw* mpd) : fMPD(mpd) {}
|
|
|
|
~AutoMPDReset() { fMPD->reset(); }
|
|
|
|
};
|
|
|
|
|
2014-12-25 21:55:08 +00:00
|
|
|
//#define FORCE_SINGLE_THREAD_DRAWING_FOR_TESTING
|
|
|
|
|
2015-01-28 19:01:06 +00:00
|
|
|
void SkMultiPictureDraw::draw(bool flush) {
|
2014-10-29 19:36:45 +00:00
|
|
|
AutoMPDReset mpdreset(this);
|
2014-12-25 21:55:08 +00:00
|
|
|
|
|
|
|
#ifdef FORCE_SINGLE_THREAD_DRAWING_FOR_TESTING
|
|
|
|
for (int i = 0; i < fThreadSafeDrawData.count(); ++i) {
|
2015-06-17 22:26:15 +00:00
|
|
|
fThreadSafeDrawData[i].draw();
|
2014-12-25 21:55:08 +00:00
|
|
|
}
|
|
|
|
#else
|
2016-01-05 03:13:19 +00:00
|
|
|
SkTaskGroup().batch(fThreadSafeDrawData.count(), [&](int i) {
|
2015-06-17 22:26:15 +00:00
|
|
|
fThreadSafeDrawData[i].draw();
|
|
|
|
});
|
2014-12-25 21:55:08 +00:00
|
|
|
#endif
|
2015-06-17 22:26:15 +00:00
|
|
|
|
|
|
|
// N.B. we could get going on any GPU work from this main thread while the CPU work runs.
|
|
|
|
// But in practice, we've either got GPU work or CPU work, not both.
|
2014-10-29 19:36:45 +00:00
|
|
|
|
|
|
|
const int count = fGPUDrawData.count();
|
|
|
|
if (0 == count) {
|
|
|
|
return;
|
|
|
|
}
|
2014-10-08 12:17:02 +00:00
|
|
|
|
2014-10-29 19:36:45 +00:00
|
|
|
for (int i = 0; i < count; ++i) {
|
|
|
|
const DrawData& data = fGPUDrawData[i];
|
|
|
|
SkCanvas* canvas = data.fCanvas;
|
|
|
|
const SkPicture* picture = data.fPicture;
|
|
|
|
|
2016-07-13 20:27:16 +00:00
|
|
|
canvas->drawPicture(picture, &data.fMatrix, data.fPaint);
|
2015-01-28 19:01:06 +00:00
|
|
|
if (flush) {
|
|
|
|
canvas->flush();
|
|
|
|
}
|
2014-10-08 12:17:02 +00:00
|
|
|
}
|
2014-08-21 20:12:42 +00:00
|
|
|
}
|