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 #ifndef SkSurface_Base_DEFINED 9 #define SkSurface_Base_DEFINED 10 11 #include "SkSurface.h" 12 #include "SkCanvas.h" 13 14 class SkSurface_Base : public SkSurface { 15 public: 16 SkSurface_Base(int width, int height); 17 explicit SkSurface_Base(const SkImageInfo&); 18 virtual ~SkSurface_Base(); 19 20 /** 21 * Allocate a canvas that will draw into this surface. We will cache this 22 * canvas, to return the same object to the caller multiple times. We 23 * take ownership, and will call unref() on the canvas when we go out of 24 * scope. 25 */ 26 virtual SkCanvas* onNewCanvas() = 0; 27 28 virtual SkSurface* onNewSurface(const SkImageInfo&) = 0; 29 30 /** 31 * Allocate an SkImage that represents the current contents of the surface. 32 * This needs to be able to outlive the surface itself (if need be), and 33 * must faithfully represent the current contents, even if the surface 34 * is chaged after this calle (e.g. it is drawn to via its canvas). 35 */ 36 virtual SkImage* onNewImageSnapshot() = 0; 37 38 /** 39 * Default implementation: 40 * 41 * image = this->newImageSnapshot(); 42 * if (image) { 43 * image->draw(canvas, ...); 44 * image->unref(); 45 * } 46 */ 47 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); 48 49 /** 50 * Called as a performance hint when the Surface is allowed to make it's contents 51 * undefined. 52 */ 53 virtual void onDiscard() {} 54 55 /** 56 * If the surface is about to change, we call this so that our subclass 57 * can optionally fork their backend (copy-on-write) in case it was 58 * being shared with the cachedImage. 59 */ 60 virtual void onCopyOnWrite(ContentChangeMode) = 0; 61 62 inline SkCanvas* getCachedCanvas(); 63 inline SkImage* getCachedImage(); 64 65 // called by SkSurface to compute a new genID 66 uint32_t newGenerationID(); 67 68 private: 69 SkCanvas* fCachedCanvas; 70 SkImage* fCachedImage; 71 72 void aboutToDraw(ContentChangeMode mode); 73 friend class SkCanvas; 74 friend class SkSurface; 75 76 typedef SkSurface INHERITED; 77 }; 78 79 SkCanvas* SkSurface_Base::getCachedCanvas() { 80 if (NULL == fCachedCanvas) { 81 fCachedCanvas = this->onNewCanvas(); 82 if (NULL != fCachedCanvas) { 83 fCachedCanvas->setSurfaceBase(this); 84 } 85 } 86 return fCachedCanvas; 87 } 88 89 SkImage* SkSurface_Base::getCachedImage() { 90 if (NULL == fCachedImage) { 91 fCachedImage = this->onNewImageSnapshot(); 92 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this); 93 } 94 return fCachedImage; 95 } 96 97 #endif 98