OLD | NEW |
(Empty) | |
| 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 |
| 8 #include "SkCanvas.h" |
| 9 #include "SkSpecialImage.h" |
| 10 #include "SkSpecialSurface.h" |
| 11 |
| 12 /////////////////////////////////////////////////////////////////////////////// |
| 13 class SkSpecialImage_Base : public SkSpecialImage { |
| 14 public: |
| 15 SkSpecialImage_Base(const SkIRect& activeRect) : INHERITED(activeRect) { } |
| 16 virtual ~SkSpecialImage_Base() { } |
| 17 |
| 18 virtual void onDraw(SkCanvas*, int x, int y, const SkPaint*) const = 0; |
| 19 |
| 20 virtual bool onPeekPixels(SkPixmap*) const { return false; } |
| 21 |
| 22 virtual GrTexture* onPeekTexture() const { return nullptr; } |
| 23 |
| 24 virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { retu
rn nullptr; } |
| 25 |
| 26 private: |
| 27 typedef SkSpecialImage INHERITED; |
| 28 }; |
| 29 |
| 30 /////////////////////////////////////////////////////////////////////////////// |
| 31 static inline const SkSpecialImage_Base* as_IB(const SkSpecialImage* image) { |
| 32 return static_cast<const SkSpecialImage_Base*>(image); |
| 33 } |
| 34 |
| 35 void SkSpecialImage::draw(SkCanvas* canvas, int x, int y, const SkPaint* paint)
const { |
| 36 return as_IB(this)->onDraw(canvas, x, y, paint); |
| 37 } |
| 38 |
| 39 bool SkSpecialImage::peekPixels(SkPixmap* pixmap) const { |
| 40 return as_IB(this)->onPeekPixels(pixmap); |
| 41 } |
| 42 |
| 43 GrTexture* SkSpecialImage::peekTexture() const { |
| 44 return as_IB(this)->onPeekTexture(); |
| 45 } |
| 46 |
| 47 SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { |
| 48 return as_IB(this)->onNewSurface(info); |
| 49 } |
| 50 |
| 51 /////////////////////////////////////////////////////////////////////////////// |
| 52 #include "SkImage.h" |
| 53 #if SK_SUPPORT_GPU |
| 54 #include "SkGr.h" |
| 55 #include "SkGrPriv.h" |
| 56 #endif |
| 57 |
| 58 class SkSpecialImage_Image : public SkSpecialImage_Base { |
| 59 public: |
| 60 SkSpecialImage_Image(const SkIRect& activeRect, const SkImage* image) |
| 61 : INHERITED(activeRect) |
| 62 , fImage(SkRef(image)) { |
| 63 } |
| 64 |
| 65 ~SkSpecialImage_Image() override { } |
| 66 |
| 67 void onDraw(SkCanvas* canvas, int x, int y, const SkPaint* paint) const over
ride { |
| 68 SkRect dst = SkRect::MakeXYWH(x, y, this->activeRect().width(), this->ac
tiveRect().height()); |
| 69 |
| 70 canvas->drawImageRect(fImage, this->activeRect(), |
| 71 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
| 72 } |
| 73 |
| 74 bool onPeekPixels(SkPixmap* pixmap) const override { |
| 75 return fImage->peekPixels(pixmap); |
| 76 } |
| 77 |
| 78 GrTexture* onPeekTexture() const override { return fImage->getTexture(); } |
| 79 |
| 80 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
| 81 #if SK_SUPPORT_GPU |
| 82 GrTexture* texture = fImage->getTexture(); |
| 83 if (texture) { |
| 84 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
| 85 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 86 |
| 87 return SkSpecialSurface::NewGpu(texture->getContext(), desc); |
| 88 } |
| 89 #endif |
| 90 return SkSpecialSurface::NewRaster(info, nullptr); |
| 91 } |
| 92 |
| 93 private: |
| 94 SkAutoTUnref<const SkImage> fImage; |
| 95 |
| 96 typedef SkSpecialImage_Base INHERITED; |
| 97 }; |
| 98 |
| 99 static bool rect_fits(const SkIRect& rect, int width, int height) { |
| 100 return rect.fLeft >= 0 && rect.fLeft < width && rect.fLeft < rect.fRight && |
| 101 rect.fRight >= 0 && rect.fRight <= width && |
| 102 rect.fTop >= 0 && rect.fTop < height && rect.fTop < rect.fBottom && |
| 103 rect.fBottom >= 0 && rect.fBottom <= height; |
| 104 } |
| 105 |
| 106 SkSpecialImage* SkSpecialImage::NewImage(const SkIRect& activeRect, const SkImag
e* image) { |
| 107 SkASSERT(rect_fits(activeRect, image->width(), image->height())); |
| 108 return new SkSpecialImage_Image(activeRect, image); |
| 109 } |
| 110 |
| 111 /////////////////////////////////////////////////////////////////////////////// |
| 112 #include "SkBitmap.h" |
| 113 #include "SkImageInfo.h" |
| 114 #include "SkPixelRef.h" |
| 115 |
| 116 class SkSpecialImage_Raster : public SkSpecialImage_Base { |
| 117 public: |
| 118 SkSpecialImage_Raster(const SkIRect& activeRect, const SkBitmap& bm) |
| 119 : INHERITED(activeRect) |
| 120 , fBitmap(bm) { |
| 121 if (bm.pixelRef()->isPreLocked()) { |
| 122 // we only preemptively lock if there is no chance of triggering som
ething expensive |
| 123 // like a lazy decode or imagegenerator. PreLocked means it is flat
pixels already. |
| 124 fBitmap.lockPixels(); |
| 125 } |
| 126 } |
| 127 |
| 128 ~SkSpecialImage_Raster() override { } |
| 129 |
| 130 void onDraw(SkCanvas* canvas, int x, int y, const SkPaint* paint) const over
ride { |
| 131 SkRect dst = SkRect::MakeXYWH(x, y, |
| 132 this->activeRect().width(), this->activeRe
ct().height()); |
| 133 |
| 134 canvas->drawBitmapRect(fBitmap, this->activeRect(), |
| 135 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
| 136 } |
| 137 |
| 138 bool onPeekPixels(SkPixmap* pixmap) const override { |
| 139 const SkImageInfo info = fBitmap.info(); |
| 140 if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels())
{ |
| 141 return false; |
| 142 } |
| 143 const void* pixels = fBitmap.getPixels(); |
| 144 if (pixels) { |
| 145 if (pixmap) { |
| 146 pixmap->reset(info, pixels, fBitmap.rowBytes()); |
| 147 } |
| 148 return true; |
| 149 } |
| 150 return false; |
| 151 } |
| 152 |
| 153 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
| 154 return SkSpecialSurface::NewRaster(info, nullptr); |
| 155 } |
| 156 |
| 157 private: |
| 158 SkBitmap fBitmap; |
| 159 |
| 160 typedef SkSpecialImage_Base INHERITED; |
| 161 }; |
| 162 |
| 163 SkSpecialImage* SkSpecialImage::NewRaster(const SkIRect& activeRect, const SkBit
map& bm) { |
| 164 SkASSERT(nullptr == bm.getTexture()); |
| 165 SkASSERT(rect_fits(activeRect, bm.width(), bm.height())); |
| 166 return new SkSpecialImage_Raster(activeRect, bm); |
| 167 } |
| 168 |
| 169 #if SK_SUPPORT_GPU |
| 170 /////////////////////////////////////////////////////////////////////////////// |
| 171 #include "GrTexture.h" |
| 172 |
| 173 class SkSpecialImage_Gpu : public SkSpecialImage_Base { |
| 174 public: |
| 175 SkSpecialImage_Gpu(const SkIRect& activeRect, GrTexture* tex) |
| 176 : INHERITED(activeRect) |
| 177 , fTexture(SkRef(tex)) { |
| 178 } |
| 179 |
| 180 ~SkSpecialImage_Gpu() override { } |
| 181 |
| 182 void onDraw(SkCanvas* canvas, int x, int y, const SkPaint* paint) const over
ride { |
| 183 SkRect dst = SkRect::MakeXYWH(x, y, |
| 184 this->activeRect().width(), this->activeRe
ct().height()); |
| 185 |
| 186 SkBitmap bm; |
| 187 |
| 188 static const bool kUnknownOpacity = false; |
| 189 GrWrapTextureInBitmap(fTexture, |
| 190 fTexture->width(), fTexture->height(), kUnknownOpa
city, &bm); |
| 191 |
| 192 canvas->drawBitmapRect(bm, this->activeRect(), |
| 193 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
| 194 } |
| 195 |
| 196 GrTexture* onPeekTexture() const override { return fTexture; } |
| 197 |
| 198 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
| 199 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
| 200 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 201 |
| 202 return SkSpecialSurface::NewGpu(fTexture->getContext(), desc); |
| 203 } |
| 204 |
| 205 private: |
| 206 SkAutoTUnref<GrTexture> fTexture; |
| 207 |
| 208 typedef SkSpecialImage_Base INHERITED; |
| 209 }; |
| 210 |
| 211 SkSpecialImage* SkSpecialImage::NewGpu(const SkIRect& activeRect, GrTexture* tex
) { |
| 212 SkASSERT(rect_fits(activeRect, tex->width(), tex->height())); |
| 213 return new SkSpecialImage_Gpu(activeRect, tex); |
| 214 } |
| 215 |
| 216 #else |
| 217 |
| 218 SkSpecialImage* SkSpecialImage::NewGpu(const SkIRect& activeRect, GrTexture* tex
) { |
| 219 return nullptr; |
| 220 } |
| 221 |
| 222 #endif |
OLD | NEW |