SkMultiPictureDraw.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright 2014 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkMultiPictureDraw.h"
  9. #include "include/core/SkPicture.h"
  10. #include "src/core/SkCanvasPriv.h"
  11. #include "src/core/SkTaskGroup.h"
  12. void SkMultiPictureDraw::DrawData::draw() {
  13. fCanvas->drawPicture(fPicture, &fMatrix, fPaint);
  14. }
  15. void SkMultiPictureDraw::DrawData::init(SkCanvas* canvas, const SkPicture* picture,
  16. const SkMatrix* matrix, const SkPaint* paint) {
  17. fPicture = SkRef(picture);
  18. fCanvas = canvas;
  19. if (matrix) {
  20. fMatrix = *matrix;
  21. } else {
  22. fMatrix.setIdentity();
  23. }
  24. if (paint) {
  25. fPaint = new SkPaint(*paint);
  26. } else {
  27. fPaint = nullptr;
  28. }
  29. }
  30. void SkMultiPictureDraw::DrawData::Reset(SkTDArray<DrawData>& data) {
  31. for (int i = 0; i < data.count(); ++i) {
  32. data[i].fPicture->unref();
  33. delete data[i].fPaint;
  34. }
  35. data.rewind();
  36. }
  37. //////////////////////////////////////////////////////////////////////////////////////
  38. SkMultiPictureDraw::SkMultiPictureDraw(int reserve) {
  39. if (reserve > 0) {
  40. fGPUDrawData.setReserve(reserve);
  41. fThreadSafeDrawData.setReserve(reserve);
  42. }
  43. }
  44. void SkMultiPictureDraw::reset() {
  45. DrawData::Reset(fGPUDrawData);
  46. DrawData::Reset(fThreadSafeDrawData);
  47. }
  48. void SkMultiPictureDraw::add(SkCanvas* canvas,
  49. const SkPicture* picture,
  50. const SkMatrix* matrix,
  51. const SkPaint* paint) {
  52. if (nullptr == canvas || nullptr == picture) {
  53. SkDEBUGFAIL("parameters to SkMultiPictureDraw::add should be non-nullptr");
  54. return;
  55. }
  56. SkTDArray<DrawData>& array = canvas->getGrContext() ? fGPUDrawData : fThreadSafeDrawData;
  57. array.append()->init(canvas, picture, matrix, paint);
  58. }
  59. class AutoMPDReset : SkNoncopyable {
  60. SkMultiPictureDraw* fMPD;
  61. public:
  62. AutoMPDReset(SkMultiPictureDraw* mpd) : fMPD(mpd) {}
  63. ~AutoMPDReset() { fMPD->reset(); }
  64. };
  65. //#define FORCE_SINGLE_THREAD_DRAWING_FOR_TESTING
  66. void SkMultiPictureDraw::draw(bool flush) {
  67. AutoMPDReset mpdreset(this);
  68. #ifdef FORCE_SINGLE_THREAD_DRAWING_FOR_TESTING
  69. for (int i = 0; i < fThreadSafeDrawData.count(); ++i) {
  70. fThreadSafeDrawData[i].draw();
  71. }
  72. #else
  73. SkTaskGroup().batch(fThreadSafeDrawData.count(), [&](int i) {
  74. fThreadSafeDrawData[i].draw();
  75. });
  76. #endif
  77. // N.B. we could get going on any GPU work from this main thread while the CPU work runs.
  78. // But in practice, we've either got GPU work or CPU work, not both.
  79. const int count = fGPUDrawData.count();
  80. if (0 == count) {
  81. return;
  82. }
  83. for (int i = 0; i < count; ++i) {
  84. const DrawData& data = fGPUDrawData[i];
  85. SkCanvas* canvas = data.fCanvas;
  86. const SkPicture* picture = data.fPicture;
  87. canvas->drawPicture(picture, &data.fMatrix, data.fPaint);
  88. if (flush) {
  89. canvas->flush();
  90. }
  91. }
  92. }