1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/image/SkSurface_Raster.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,161 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkSurface_Base.h" 1.12 +#include "SkImagePriv.h" 1.13 +#include "SkCanvas.h" 1.14 +#include "SkDevice.h" 1.15 +#include "SkMallocPixelRef.h" 1.16 + 1.17 +static const size_t kIgnoreRowBytesValue = (size_t)~0; 1.18 + 1.19 +class SkSurface_Raster : public SkSurface_Base { 1.20 +public: 1.21 + static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue); 1.22 + 1.23 + SkSurface_Raster(const SkImageInfo&, void*, size_t rb); 1.24 + SkSurface_Raster(SkPixelRef*); 1.25 + 1.26 + virtual SkCanvas* onNewCanvas() SK_OVERRIDE; 1.27 + virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; 1.28 + virtual SkImage* onNewImageSnapshot() SK_OVERRIDE; 1.29 + virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, 1.30 + const SkPaint*) SK_OVERRIDE; 1.31 + virtual void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE; 1.32 + 1.33 +private: 1.34 + SkBitmap fBitmap; 1.35 + bool fWeOwnThePixels; 1.36 + 1.37 + typedef SkSurface_Base INHERITED; 1.38 +}; 1.39 + 1.40 +/////////////////////////////////////////////////////////////////////////////// 1.41 + 1.42 +bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { 1.43 + static const size_t kMaxTotalSize = SK_MaxS32; 1.44 + 1.45 + int shift = 0; 1.46 + switch (info.fColorType) { 1.47 + case kAlpha_8_SkColorType: 1.48 + shift = 0; 1.49 + break; 1.50 + case kRGB_565_SkColorType: 1.51 + shift = 1; 1.52 + break; 1.53 + case kPMColor_SkColorType: 1.54 + shift = 2; 1.55 + break; 1.56 + default: 1.57 + return false; 1.58 + } 1.59 + 1.60 + if (kIgnoreRowBytesValue == rowBytes) { 1.61 + return true; 1.62 + } 1.63 + 1.64 + uint64_t minRB = (uint64_t)info.fWidth << shift; 1.65 + if (minRB > rowBytes) { 1.66 + return false; 1.67 + } 1.68 + 1.69 + size_t alignedRowBytes = rowBytes >> shift << shift; 1.70 + if (alignedRowBytes != rowBytes) { 1.71 + return false; 1.72 + } 1.73 + 1.74 + uint64_t size = sk_64_mul(info.fHeight, rowBytes); 1.75 + if (size > kMaxTotalSize) { 1.76 + return false; 1.77 + } 1.78 + 1.79 + return true; 1.80 +} 1.81 + 1.82 +SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb) 1.83 + : INHERITED(info) 1.84 +{ 1.85 + fBitmap.setConfig(info, rb); 1.86 + fBitmap.setPixels(pixels); 1.87 + fWeOwnThePixels = false; // We are "Direct" 1.88 +} 1.89 + 1.90 +SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr) 1.91 + : INHERITED(pr->info().fWidth, pr->info().fHeight) 1.92 +{ 1.93 + const SkImageInfo& info = pr->info(); 1.94 + 1.95 + fBitmap.setConfig(info, info.minRowBytes()); 1.96 + fBitmap.setPixelRef(pr); 1.97 + fWeOwnThePixels = true; 1.98 + 1.99 + if (!info.isOpaque()) { 1.100 + fBitmap.eraseColor(SK_ColorTRANSPARENT); 1.101 + } 1.102 +} 1.103 + 1.104 +SkCanvas* SkSurface_Raster::onNewCanvas() { 1.105 + return SkNEW_ARGS(SkCanvas, (fBitmap)); 1.106 +} 1.107 + 1.108 +SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) { 1.109 + return SkSurface::NewRaster(info); 1.110 +} 1.111 + 1.112 +void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 1.113 + const SkPaint* paint) { 1.114 + canvas->drawBitmap(fBitmap, x, y, paint); 1.115 +} 1.116 + 1.117 +SkImage* SkSurface_Raster::onNewImageSnapshot() { 1.118 + return SkNewImageFromBitmap(fBitmap, fWeOwnThePixels); 1.119 +} 1.120 + 1.121 +void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { 1.122 + // are we sharing pixelrefs with the image? 1.123 + SkASSERT(NULL != this->getCachedImage()); 1.124 + if (SkBitmapImageGetPixelRef(this->getCachedImage()) == fBitmap.pixelRef()) { 1.125 + SkASSERT(fWeOwnThePixels); 1.126 + if (kDiscard_ContentChangeMode == mode) { 1.127 + fBitmap.setPixelRef(NULL); 1.128 + fBitmap.allocPixels(); 1.129 + } else { 1.130 + SkBitmap prev(fBitmap); 1.131 + prev.deepCopyTo(&fBitmap); 1.132 + } 1.133 + // Now fBitmap is a deep copy of itself (and therefore different from 1.134 + // what is being used by the image. Next we update the canvas to use 1.135 + // this as its backend, so we can't modify the image's pixels anymore. 1.136 + SkASSERT(NULL != this->getCachedCanvas()); 1.137 + this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap); 1.138 + } 1.139 +} 1.140 + 1.141 +/////////////////////////////////////////////////////////////////////////////// 1.142 + 1.143 +SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 1.144 + if (!SkSurface_Raster::Valid(info, rowBytes)) { 1.145 + return NULL; 1.146 + } 1.147 + if (NULL == pixels) { 1.148 + return NULL; 1.149 + } 1.150 + 1.151 + return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rowBytes)); 1.152 +} 1.153 + 1.154 +SkSurface* SkSurface::NewRaster(const SkImageInfo& info) { 1.155 + if (!SkSurface_Raster::Valid(info)) { 1.156 + return NULL; 1.157 + } 1.158 + 1.159 + SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL)); 1.160 + if (NULL == pr.get()) { 1.161 + return NULL; 1.162 + } 1.163 + return SkNEW_ARGS(SkSurface_Raster, (pr)); 1.164 +}