1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/image/SkSurface.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,127 @@ 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 + 1.15 +/////////////////////////////////////////////////////////////////////////////// 1.16 + 1.17 +SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) { 1.18 + fCachedCanvas = NULL; 1.19 + fCachedImage = NULL; 1.20 +} 1.21 + 1.22 +SkSurface_Base::SkSurface_Base(const SkImageInfo& info) : INHERITED(info) { 1.23 + fCachedCanvas = NULL; 1.24 + fCachedImage = NULL; 1.25 +} 1.26 + 1.27 +SkSurface_Base::~SkSurface_Base() { 1.28 + // in case the canvas outsurvives us, we null the callback 1.29 + if (fCachedCanvas) { 1.30 + fCachedCanvas->setSurfaceBase(NULL); 1.31 + } 1.32 + 1.33 + SkSafeUnref(fCachedImage); 1.34 + SkSafeUnref(fCachedCanvas); 1.35 +} 1.36 + 1.37 +void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 1.38 + const SkPaint* paint) { 1.39 + SkImage* image = this->newImageSnapshot(); 1.40 + if (image) { 1.41 + image->draw(canvas, x, y, paint); 1.42 + image->unref(); 1.43 + } 1.44 +} 1.45 + 1.46 +void SkSurface_Base::aboutToDraw(ContentChangeMode mode) { 1.47 + this->dirtyGenerationID(); 1.48 + 1.49 + if (NULL != fCachedCanvas) { 1.50 + SkASSERT(fCachedCanvas->getSurfaceBase() == this || \ 1.51 + NULL == fCachedCanvas->getSurfaceBase()); 1.52 + fCachedCanvas->setSurfaceBase(NULL); 1.53 + } 1.54 + 1.55 + if (NULL != fCachedImage) { 1.56 + // the surface may need to fork its backend, if its sharing it with 1.57 + // the cached image. Note: we only call if there is an outstanding owner 1.58 + // on the image (besides us). 1.59 + if (!fCachedImage->unique()) { 1.60 + this->onCopyOnWrite(mode); 1.61 + } 1.62 + 1.63 + // regardless of copy-on-write, we must drop our cached image now, so 1.64 + // that the next request will get our new contents. 1.65 + fCachedImage->unref(); 1.66 + fCachedImage = NULL; 1.67 + } 1.68 +} 1.69 + 1.70 +uint32_t SkSurface_Base::newGenerationID() { 1.71 + this->installIntoCanvasForDirtyNotification(); 1.72 + 1.73 + static int32_t gID; 1.74 + return sk_atomic_inc(&gID) + 1; 1.75 +} 1.76 + 1.77 +static SkSurface_Base* asSB(SkSurface* surface) { 1.78 + return static_cast<SkSurface_Base*>(surface); 1.79 +} 1.80 + 1.81 +/////////////////////////////////////////////////////////////////////////////// 1.82 + 1.83 +SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) { 1.84 + SkASSERT(fWidth >= 0); 1.85 + SkASSERT(fHeight >= 0); 1.86 + fGenerationID = 0; 1.87 +} 1.88 + 1.89 +SkSurface::SkSurface(const SkImageInfo& info) 1.90 + : fWidth(info.fWidth) 1.91 + , fHeight(info.fHeight) 1.92 +{ 1.93 + SkASSERT(fWidth >= 0); 1.94 + SkASSERT(fHeight >= 0); 1.95 + fGenerationID = 0; 1.96 +} 1.97 + 1.98 +uint32_t SkSurface::generationID() { 1.99 + if (0 == fGenerationID) { 1.100 + fGenerationID = asSB(this)->newGenerationID(); 1.101 + } 1.102 + return fGenerationID; 1.103 +} 1.104 + 1.105 +void SkSurface::notifyContentWillChange(ContentChangeMode mode) { 1.106 + asSB(this)->aboutToDraw(mode); 1.107 +} 1.108 + 1.109 +SkCanvas* SkSurface::getCanvas() { 1.110 + return asSB(this)->getCachedCanvas(); 1.111 +} 1.112 + 1.113 +SkImage* SkSurface::newImageSnapshot() { 1.114 + SkImage* image = asSB(this)->getCachedImage(); 1.115 + SkSafeRef(image); // the caller will call unref() to balance this 1.116 + return image; 1.117 +} 1.118 + 1.119 +SkSurface* SkSurface::newSurface(const SkImageInfo& info) { 1.120 + return asSB(this)->onNewSurface(info); 1.121 +} 1.122 + 1.123 +void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, 1.124 + const SkPaint* paint) { 1.125 + return asSB(this)->onDraw(canvas, x, y, paint); 1.126 +} 1.127 + 1.128 +const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1.129 + return this->getCanvas()->peekPixels(info, rowBytes); 1.130 +}