1 /* 2 * Copyright 2012 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 "SkSurface_Base.h" 9 #include "SkImagePriv.h" 10 #include "SkCanvas.h" 11 #include "SkDevice.h" 12 #include "SkMallocPixelRef.h" 13 14 static const size_t kIgnoreRowBytesValue = (size_t)~0; 15 16 class SkSurface_Raster : public SkSurface_Base { 17 public: 18 static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue); 19 20 SkSurface_Raster(const SkImageInfo&, void*, size_t rb, 21 void (*releaseProc)(void* pixels, void* context), void* context, 22 const SkSurfaceProps*); 23 SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*); 24 25 virtual SkCanvas* onNewCanvas() SK_OVERRIDE; 26 virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; 27 virtual SkImage* onNewImageSnapshot() SK_OVERRIDE; 28 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, 29 const SkPaint*) SK_OVERRIDE; 30 virtual void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE; 31 32 private: 33 SkBitmap fBitmap; 34 bool fWeOwnThePixels; 35 36 typedef SkSurface_Base INHERITED; 37 }; 38 39 /////////////////////////////////////////////////////////////////////////////// 40 41 bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { 42 static const size_t kMaxTotalSize = SK_MaxS32; 43 44 int shift = 0; 45 switch (info.colorType()) { 46 case kAlpha_8_SkColorType: 47 shift = 0; 48 break; 49 case kRGB_565_SkColorType: 50 shift = 1; 51 break; 52 case kN32_SkColorType: 53 shift = 2; 54 break; 55 default: 56 return false; 57 } 58 59 if (kIgnoreRowBytesValue == rowBytes) { 60 return true; 61 } 62 63 uint64_t minRB = (uint64_t)info.width() << shift; 64 if (minRB > rowBytes) { 65 return false; 66 } 67 68 size_t alignedRowBytes = rowBytes >> shift << shift; 69 if (alignedRowBytes != rowBytes) { 70 return false; 71 } 72 73 uint64_t size = sk_64_mul(info.height(), rowBytes); 74 if (size > kMaxTotalSize) { 75 return false; 76 } 77 78 return true; 79 } 80 81 SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb, 82 void (*releaseProc)(void* pixels, void* context), void* context, 83 const SkSurfaceProps* props) 84 : INHERITED(info, props) 85 { 86 fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); 87 fWeOwnThePixels = false; // We are "Direct" 88 } 89 90 SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) 91 : INHERITED(pr->info().width(), pr->info().height(), props) 92 { 93 const SkImageInfo& info = pr->info(); 94 95 fBitmap.setInfo(info, info.minRowBytes()); 96 fBitmap.setPixelRef(pr); 97 fWeOwnThePixels = true; 98 99 if (!info.isOpaque()) { 100 fBitmap.eraseColor(SK_ColorTRANSPARENT); 101 } 102 } 103 104 SkCanvas* SkSurface_Raster::onNewCanvas() { 105 return SkNEW_ARGS(SkCanvas, (fBitmap, this->props())); 106 } 107 108 SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) { 109 return SkSurface::NewRaster(info); 110 } 111 112 void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 113 const SkPaint* paint) { 114 canvas->drawBitmap(fBitmap, x, y, paint); 115 } 116 117 SkImage* SkSurface_Raster::onNewImageSnapshot() { 118 return SkNewImageFromBitmap(fBitmap, fWeOwnThePixels); 119 } 120 121 void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { 122 // are we sharing pixelrefs with the image? 123 SkASSERT(this->getCachedImage()); 124 if (SkBitmapImageGetPixelRef(this->getCachedImage()) == fBitmap.pixelRef()) { 125 SkASSERT(fWeOwnThePixels); 126 if (kDiscard_ContentChangeMode == mode) { 127 fBitmap.setPixelRef(NULL); 128 fBitmap.allocPixels(); 129 } else { 130 SkBitmap prev(fBitmap); 131 prev.deepCopyTo(&fBitmap); 132 } 133 // Now fBitmap is a deep copy of itself (and therefore different from 134 // what is being used by the image. Next we update the canvas to use 135 // this as its backend, so we can't modify the image's pixels anymore. 136 SkASSERT(this->getCachedCanvas()); 137 this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap); 138 } 139 } 140 141 /////////////////////////////////////////////////////////////////////////////// 142 143 SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void* pixels, size_t rb, 144 void (*releaseProc)(void* pixels, void* context), 145 void* context, const SkSurfaceProps* props) { 146 if (NULL == releaseProc) { 147 context = NULL; 148 } 149 if (!SkSurface_Raster::Valid(info, rb)) { 150 return NULL; 151 } 152 if (NULL == pixels) { 153 return NULL; 154 } 155 156 return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rb, releaseProc, context, props)); 157 } 158 159 SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes, 160 const SkSurfaceProps* props) { 161 return NewRasterDirectReleaseProc(info, pixels, rowBytes, NULL, NULL, props); 162 } 163 164 SkSurface* SkSurface::NewRaster(const SkImageInfo& info, const SkSurfaceProps* props) { 165 if (!SkSurface_Raster::Valid(info)) { 166 return NULL; 167 } 168 169 SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL)); 170 if (NULL == pr.get()) { 171 return NULL; 172 } 173 return SkNEW_ARGS(SkSurface_Raster, (pr, props)); 174 } 175