SkSpecialSurface.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright 2016 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 "src/core/SkSpecialImage.h"
  9. #include "src/core/SkSpecialSurface.h"
  10. #include "src/core/SkSurfacePriv.h"
  11. ///////////////////////////////////////////////////////////////////////////////
  12. class SkSpecialSurface_Base : public SkSpecialSurface {
  13. public:
  14. SkSpecialSurface_Base(const SkIRect& subset, const SkSurfaceProps* props)
  15. : INHERITED(subset, props)
  16. , fCanvas(nullptr) {
  17. }
  18. virtual ~SkSpecialSurface_Base() { }
  19. // reset is called after an SkSpecialImage has been snapped
  20. void reset() { fCanvas.reset(); }
  21. // This can return nullptr if reset has already been called or something when wrong in the ctor
  22. SkCanvas* onGetCanvas() { return fCanvas.get(); }
  23. virtual sk_sp<SkSpecialImage> onMakeImageSnapshot() = 0;
  24. protected:
  25. std::unique_ptr<SkCanvas> fCanvas; // initialized by derived classes in ctors
  26. private:
  27. typedef SkSpecialSurface INHERITED;
  28. };
  29. ///////////////////////////////////////////////////////////////////////////////
  30. static SkSpecialSurface_Base* as_SB(SkSpecialSurface* surface) {
  31. return static_cast<SkSpecialSurface_Base*>(surface);
  32. }
  33. SkSpecialSurface::SkSpecialSurface(const SkIRect& subset,
  34. const SkSurfaceProps* props)
  35. : fProps(SkSurfacePropsCopyOrDefault(props).flags(), kUnknown_SkPixelGeometry)
  36. , fSubset(subset) {
  37. SkASSERT(fSubset.width() > 0);
  38. SkASSERT(fSubset.height() > 0);
  39. }
  40. SkCanvas* SkSpecialSurface::getCanvas() {
  41. return as_SB(this)->onGetCanvas();
  42. }
  43. sk_sp<SkSpecialImage> SkSpecialSurface::makeImageSnapshot() {
  44. sk_sp<SkSpecialImage> image(as_SB(this)->onMakeImageSnapshot());
  45. as_SB(this)->reset();
  46. return image; // the caller gets the creation ref
  47. }
  48. ///////////////////////////////////////////////////////////////////////////////
  49. #include "include/core/SkMallocPixelRef.h"
  50. class SkSpecialSurface_Raster : public SkSpecialSurface_Base {
  51. public:
  52. SkSpecialSurface_Raster(const SkImageInfo& info,
  53. sk_sp<SkPixelRef> pr,
  54. const SkIRect& subset,
  55. const SkSurfaceProps* props)
  56. : INHERITED(subset, props) {
  57. SkASSERT(info.width() == pr->width() && info.height() == pr->height());
  58. fBitmap.setInfo(info, info.minRowBytes());
  59. fBitmap.setPixelRef(std::move(pr), 0, 0);
  60. fCanvas.reset(new SkCanvas(fBitmap, this->props()));
  61. fCanvas->clipRect(SkRect::Make(subset));
  62. #ifdef SK_IS_BOT
  63. fCanvas->clear(SK_ColorRED); // catch any imageFilter sloppiness
  64. #endif
  65. }
  66. ~SkSpecialSurface_Raster() override { }
  67. sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
  68. return SkSpecialImage::MakeFromRaster(this->subset(), fBitmap, &this->props());
  69. }
  70. private:
  71. SkBitmap fBitmap;
  72. typedef SkSpecialSurface_Base INHERITED;
  73. };
  74. sk_sp<SkSpecialSurface> SkSpecialSurface::MakeFromBitmap(const SkIRect& subset, SkBitmap& bm,
  75. const SkSurfaceProps* props) {
  76. if (subset.isEmpty() || !SkSurfaceValidateRasterInfo(bm.info(), bm.rowBytes())) {
  77. return nullptr;
  78. }
  79. return sk_make_sp<SkSpecialSurface_Raster>(bm.info(), sk_ref_sp(bm.pixelRef()), subset, props);
  80. }
  81. sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRaster(const SkImageInfo& info,
  82. const SkSurfaceProps* props) {
  83. if (!SkSurfaceValidateRasterInfo(info)) {
  84. return nullptr;
  85. }
  86. sk_sp<SkPixelRef> pr = SkMallocPixelRef::MakeAllocate(info, 0);
  87. if (!pr) {
  88. return nullptr;
  89. }
  90. const SkIRect subset = SkIRect::MakeWH(info.width(), info.height());
  91. return sk_make_sp<SkSpecialSurface_Raster>(info, std::move(pr), subset, props);
  92. }
  93. #if SK_SUPPORT_GPU
  94. ///////////////////////////////////////////////////////////////////////////////
  95. #include "include/gpu/GrBackendSurface.h"
  96. #include "include/private/GrRecordingContext.h"
  97. #include "src/gpu/GrRecordingContextPriv.h"
  98. #include "src/gpu/SkGpuDevice.h"
  99. class SkSpecialSurface_Gpu : public SkSpecialSurface_Base {
  100. public:
  101. SkSpecialSurface_Gpu(GrRecordingContext* context,
  102. sk_sp<GrRenderTargetContext> renderTargetContext,
  103. int width, int height, const SkIRect& subset)
  104. : INHERITED(subset, &renderTargetContext->surfaceProps())
  105. , fRenderTargetContext(std::move(renderTargetContext)) {
  106. // CONTEXT TODO: remove this use of 'backdoor' to create an SkGpuDevice
  107. sk_sp<SkBaseDevice> device(SkGpuDevice::Make(context->priv().backdoor(),
  108. fRenderTargetContext, width, height,
  109. SkGpuDevice::kUninit_InitContents));
  110. if (!device) {
  111. return;
  112. }
  113. fCanvas.reset(new SkCanvas(device));
  114. fCanvas->clipRect(SkRect::Make(subset));
  115. #ifdef SK_IS_BOT
  116. fCanvas->clear(SK_ColorRED); // catch any imageFilter sloppiness
  117. #endif
  118. }
  119. ~SkSpecialSurface_Gpu() override { }
  120. sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
  121. if (!fRenderTargetContext->asTextureProxy()) {
  122. return nullptr;
  123. }
  124. sk_sp<SkSpecialImage> tmp(SkSpecialImage::MakeDeferredFromGpu(
  125. fCanvas->getGrContext(),
  126. this->subset(),
  127. kNeedNewImageUniqueID_SpecialImage,
  128. fRenderTargetContext->asTextureProxyRef(),
  129. fRenderTargetContext->colorSpaceInfo().refColorSpace(),
  130. &this->props()));
  131. fRenderTargetContext = nullptr;
  132. return tmp;
  133. }
  134. private:
  135. sk_sp<GrRenderTargetContext> fRenderTargetContext;
  136. typedef SkSpecialSurface_Base INHERITED;
  137. };
  138. sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrRecordingContext* context,
  139. int width, int height,
  140. GrColorType colorType,
  141. sk_sp<SkColorSpace> colorSpace,
  142. const SkSurfaceProps* props) {
  143. if (!context) {
  144. return nullptr;
  145. }
  146. sk_sp<GrRenderTargetContext> renderTargetContext(
  147. context->priv().makeDeferredRenderTargetContext(
  148. SkBackingFit::kApprox, width, height, colorType, std::move(colorSpace), 1,
  149. GrMipMapped::kNo, kBottomLeft_GrSurfaceOrigin, props));
  150. if (!renderTargetContext) {
  151. return nullptr;
  152. }
  153. const SkIRect subset = SkIRect::MakeWH(width, height);
  154. return sk_make_sp<SkSpecialSurface_Gpu>(context, std::move(renderTargetContext),
  155. width, height, subset);
  156. }
  157. #endif