blob: 2dde36b96d95c89ce8834d5cbc3c783004971809 [file] [log] [blame]
reed@google.comc9062042012-07-30 18:06:00 +00001/*
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
reed@google.com9ea5a3b2012-07-30 21:03:46 +00008#include "SkSurface_Base.h"
reed@google.com889b09e2012-07-27 21:10:42 +00009#include "SkImagePriv.h"
10#include "SkCanvas.h"
11
12///////////////////////////////////////////////////////////////////////////////
13
reed@google.com9ea5a3b2012-07-30 21:03:46 +000014SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) {
15 fCachedCanvas = NULL;
reed@google.com97af1a62012-08-28 12:19:02 +000016 fCachedImage = NULL;
reed@google.com9ea5a3b2012-07-30 21:03:46 +000017}
reed@google.com889b09e2012-07-27 21:10:42 +000018
reed@google.com9ea5a3b2012-07-30 21:03:46 +000019SkSurface_Base::~SkSurface_Base() {
reed@google.com97af1a62012-08-28 12:19:02 +000020 // in case the canvas outsurvives us, we null the callback
21 if (fCachedCanvas) {
22 fCachedCanvas->setSurfaceBase(NULL);
23 }
24
25 SkSafeUnref(fCachedImage);
reed@google.com9ea5a3b2012-07-30 21:03:46 +000026 SkSafeUnref(fCachedCanvas);
27}
reed@google.com889b09e2012-07-27 21:10:42 +000028
29void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
30 const SkPaint* paint) {
junov@chromium.org5ee449a2013-04-12 20:20:50 +000031 SkImage* image = this->newImageSnapshot();
reed@google.com889b09e2012-07-27 21:10:42 +000032 if (image) {
33 image->draw(canvas, x, y, paint);
34 image->unref();
35 }
36}
37
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000038void SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
reed@google.com97af1a62012-08-28 12:19:02 +000039 this->dirtyGenerationID();
40
junov@chromium.orgacea3ef2013-04-16 19:41:09 +000041 if (NULL != fCachedCanvas) {
42 SkASSERT(fCachedCanvas->getSurfaceBase() == this || \
43 NULL == fCachedCanvas->getSurfaceBase());
44 fCachedCanvas->setSurfaceBase(NULL);
reed@google.com97af1a62012-08-28 12:19:02 +000045 }
46
junov@chromium.orgacea3ef2013-04-16 19:41:09 +000047 if (NULL != fCachedImage) {
reed@google.com97af1a62012-08-28 12:19:02 +000048 // the surface may need to fork its backend, if its sharing it with
49 // the cached image. Note: we only call if there is an outstanding owner
50 // on the image (besides us).
bungeman@google.comf64c6842013-07-19 23:18:52 +000051 if (!fCachedImage->unique()) {
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000052 this->onCopyOnWrite(mode);
reed@google.com97af1a62012-08-28 12:19:02 +000053 }
54
55 // regardless of copy-on-write, we must drop our cached image now, so
56 // that the next request will get our new contents.
57 fCachedImage->unref();
58 fCachedImage = NULL;
59 }
60}
61
62uint32_t SkSurface_Base::newGenerationID() {
63 this->installIntoCanvasForDirtyNotification();
64
65 static int32_t gID;
66 return sk_atomic_inc(&gID) + 1;
67}
68
reed@google.com889b09e2012-07-27 21:10:42 +000069static SkSurface_Base* asSB(SkSurface* surface) {
70 return static_cast<SkSurface_Base*>(surface);
71}
72
73///////////////////////////////////////////////////////////////////////////////
74
75SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
76 SkASSERT(width >= 0);
77 SkASSERT(height >= 0);
78 fGenerationID = 0;
79}
80
reed@google.com97af1a62012-08-28 12:19:02 +000081uint32_t SkSurface::generationID() {
82 if (0 == fGenerationID) {
83 fGenerationID = asSB(this)->newGenerationID();
84 }
85 return fGenerationID;
86}
87
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000088void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
89 asSB(this)->aboutToDraw(mode);
reed@google.com97af1a62012-08-28 12:19:02 +000090}
91
reed@google.com9ea5a3b2012-07-30 21:03:46 +000092SkCanvas* SkSurface::getCanvas() {
93 return asSB(this)->getCachedCanvas();
reed@google.com889b09e2012-07-27 21:10:42 +000094}
95
junov@chromium.org5ee449a2013-04-12 20:20:50 +000096SkImage* SkSurface::newImageSnapshot() {
reed@google.com97af1a62012-08-28 12:19:02 +000097 SkImage* image = asSB(this)->getCachedImage();
98 SkSafeRef(image); // the caller will call unref() to balance this
99 return image;
reed@google.com889b09e2012-07-27 21:10:42 +0000100}
101
reed@google.com2bd8b812013-11-01 13:46:54 +0000102SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +0000103 return asSB(this)->onNewSurface(info);
reed@google.com889b09e2012-07-27 21:10:42 +0000104}
105
106void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
107 const SkPaint* paint) {
108 return asSB(this)->onDraw(canvas, x, y, paint);
109}