drawminibitmaprect.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright 2015 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 "gm/gm.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkColor.h"
  10. #include "include/core/SkImage.h"
  11. #include "include/core/SkImageInfo.h"
  12. #include "include/core/SkMatrix.h"
  13. #include "include/core/SkPaint.h"
  14. #include "include/core/SkPoint.h"
  15. #include "include/core/SkRect.h"
  16. #include "include/core/SkRefCnt.h"
  17. #include "include/core/SkScalar.h"
  18. #include "include/core/SkShader.h"
  19. #include "include/core/SkSize.h"
  20. #include "include/core/SkString.h"
  21. #include "include/core/SkSurface.h"
  22. #include "include/core/SkTileMode.h"
  23. #include "include/core/SkTypes.h"
  24. #include "include/effects/SkGradientShader.h"
  25. #include "include/utils/SkRandom.h"
  26. #include "src/core/SkMathPriv.h"
  27. static sk_sp<SkImage> makebm(int w, int h) {
  28. SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
  29. auto surface(SkSurface::MakeRaster(info));
  30. SkCanvas* canvas = surface->getCanvas();
  31. const SkScalar wScalar = SkIntToScalar(w);
  32. const SkScalar hScalar = SkIntToScalar(h);
  33. const SkPoint pt = { wScalar / 2, hScalar / 2 };
  34. const SkScalar radius = 4 * SkMaxScalar(wScalar, hScalar);
  35. constexpr SkColor colors[] = { SK_ColorRED, SK_ColorYELLOW,
  36. SK_ColorGREEN, SK_ColorMAGENTA,
  37. SK_ColorBLUE, SK_ColorCYAN,
  38. SK_ColorRED};
  39. constexpr SkScalar pos[] = {0,
  40. SK_Scalar1 / 6,
  41. 2 * SK_Scalar1 / 6,
  42. 3 * SK_Scalar1 / 6,
  43. 4 * SK_Scalar1 / 6,
  44. 5 * SK_Scalar1 / 6,
  45. SK_Scalar1};
  46. SkASSERT(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(pos));
  47. SkPaint paint;
  48. SkRect rect = SkRect::MakeWH(wScalar, hScalar);
  49. SkMatrix mat = SkMatrix::I();
  50. for (int i = 0; i < 4; ++i) {
  51. paint.setShader(SkGradientShader::MakeRadial(
  52. pt, radius,
  53. colors, pos,
  54. SK_ARRAY_COUNT(colors),
  55. SkTileMode::kRepeat,
  56. 0, &mat));
  57. canvas->drawRect(rect, paint);
  58. rect.inset(wScalar / 8, hScalar / 8);
  59. mat.postScale(SK_Scalar1 / 4, SK_Scalar1 / 4);
  60. }
  61. return surface->makeImageSnapshot();
  62. }
  63. constexpr int gSize = 1024;
  64. constexpr int gSurfaceSize = 2048;
  65. // This GM calls drawImageRect several times using the same texture. This is intended to exercise
  66. // combining GrDrawOps during these calls.
  67. class DrawMiniBitmapRectGM : public skiagm::GM {
  68. public:
  69. DrawMiniBitmapRectGM(bool antiAlias) : fAA(antiAlias) {
  70. fName.set("drawminibitmaprect");
  71. if (fAA) {
  72. fName.appendf("_aa");
  73. }
  74. }
  75. protected:
  76. SkString onShortName() override { return fName; }
  77. SkISize onISize() override { return SkISize::Make(gSize, gSize); }
  78. void onDraw(SkCanvas* canvas) override {
  79. if (nullptr == fImage) {
  80. fImage = makebm(gSurfaceSize, gSurfaceSize);
  81. }
  82. const SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)};
  83. const int kMaxSrcRectSize = 1 << (SkNextLog2(gSurfaceSize) + 2);
  84. constexpr int kPadX = 30;
  85. constexpr int kPadY = 40;
  86. int rowCount = 0;
  87. canvas->translate(SkIntToScalar(kPadX), SkIntToScalar(kPadY));
  88. canvas->save();
  89. SkRandom random;
  90. SkPaint paint;
  91. paint.setAntiAlias(fAA);
  92. for (int w = 1; w <= kMaxSrcRectSize; w *= 3) {
  93. for (int h = 1; h <= kMaxSrcRectSize; h *= 3) {
  94. const SkIRect srcRect =
  95. SkIRect::MakeXYWH((gSurfaceSize - w) / 2, (gSurfaceSize - h) / 2, w, h);
  96. canvas->save();
  97. switch (random.nextU() % 3) {
  98. case 0:
  99. canvas->rotate(random.nextF() * 10.f);
  100. break;
  101. case 1:
  102. canvas->rotate(-random.nextF() * 10.f);
  103. break;
  104. case 2:
  105. // rect stays rect
  106. break;
  107. }
  108. canvas->drawImageRect(fImage.get(), srcRect, dstRect, &paint,
  109. SkCanvas::kFast_SrcRectConstraint);
  110. canvas->restore();
  111. canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0);
  112. ++rowCount;
  113. if ((dstRect.width() + 2 * kPadX) * rowCount > gSize) {
  114. canvas->restore();
  115. canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY);
  116. canvas->save();
  117. rowCount = 0;
  118. }
  119. }
  120. }
  121. canvas->restore();
  122. }
  123. private:
  124. bool fAA;
  125. sk_sp<SkImage> fImage;
  126. SkString fName;
  127. typedef skiagm::GM INHERITED;
  128. };
  129. DEF_GM( return new DrawMiniBitmapRectGM(true); )
  130. DEF_GM( return new DrawMiniBitmapRectGM(false); )