blob: ecb80427576de2ae2b99bf8235662d8820f65315 [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.com1360c522014-01-08 21:25:26 +000019SkSurface_Base::SkSurface_Base(const SkImageInfo& info) : INHERITED(info) {
20 fCachedCanvas = NULL;
21 fCachedImage = NULL;
22}
23
reed@google.com9ea5a3b2012-07-30 21:03:46 +000024SkSurface_Base::~SkSurface_Base() {
reed@google.com97af1a62012-08-28 12:19:02 +000025 // in case the canvas outsurvives us, we null the callback
26 if (fCachedCanvas) {
27 fCachedCanvas->setSurfaceBase(NULL);
28 }
29
30 SkSafeUnref(fCachedImage);
reed@google.com9ea5a3b2012-07-30 21:03:46 +000031 SkSafeUnref(fCachedCanvas);
32}
reed@google.com889b09e2012-07-27 21:10:42 +000033
34void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
35 const SkPaint* paint) {
junov@chromium.org5ee449a2013-04-12 20:20:50 +000036 SkImage* image = this->newImageSnapshot();
reed@google.com889b09e2012-07-27 21:10:42 +000037 if (image) {
38 image->draw(canvas, x, y, paint);
39 image->unref();
40 }
41}
42
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000043void SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
reed@google.com97af1a62012-08-28 12:19:02 +000044 this->dirtyGenerationID();
45
junov@chromium.orgacea3ef2013-04-16 19:41:09 +000046 if (NULL != fCachedCanvas) {
47 SkASSERT(fCachedCanvas->getSurfaceBase() == this || \
48 NULL == fCachedCanvas->getSurfaceBase());
49 fCachedCanvas->setSurfaceBase(NULL);
reed@google.com97af1a62012-08-28 12:19:02 +000050 }
51
junov@chromium.orgacea3ef2013-04-16 19:41:09 +000052 if (NULL != fCachedImage) {
reed@google.com97af1a62012-08-28 12:19:02 +000053 // the surface may need to fork its backend, if its sharing it with
54 // the cached image. Note: we only call if there is an outstanding owner
55 // on the image (besides us).
bungeman@google.comf64c6842013-07-19 23:18:52 +000056 if (!fCachedImage->unique()) {
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000057 this->onCopyOnWrite(mode);
reed@google.com97af1a62012-08-28 12:19:02 +000058 }
59
60 // regardless of copy-on-write, we must drop our cached image now, so
61 // that the next request will get our new contents.
62 fCachedImage->unref();
63 fCachedImage = NULL;
64 }
65}
66
67uint32_t SkSurface_Base::newGenerationID() {
68 this->installIntoCanvasForDirtyNotification();
69
70 static int32_t gID;
71 return sk_atomic_inc(&gID) + 1;
72}
73
reed@google.com889b09e2012-07-27 21:10:42 +000074static SkSurface_Base* asSB(SkSurface* surface) {
75 return static_cast<SkSurface_Base*>(surface);
76}
77
78///////////////////////////////////////////////////////////////////////////////
79
80SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
reed@google.com1360c522014-01-08 21:25:26 +000081 SkASSERT(fWidth >= 0);
82 SkASSERT(fHeight >= 0);
83 fGenerationID = 0;
84}
85
86SkSurface::SkSurface(const SkImageInfo& info)
87 : fWidth(info.fWidth)
88 , fHeight(info.fHeight)
89{
90 SkASSERT(fWidth >= 0);
91 SkASSERT(fHeight >= 0);
reed@google.com889b09e2012-07-27 21:10:42 +000092 fGenerationID = 0;
93}
94
reed@google.com97af1a62012-08-28 12:19:02 +000095uint32_t SkSurface::generationID() {
96 if (0 == fGenerationID) {
97 fGenerationID = asSB(this)->newGenerationID();
98 }
99 return fGenerationID;
100}
101
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +0000102void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
103 asSB(this)->aboutToDraw(mode);
reed@google.com97af1a62012-08-28 12:19:02 +0000104}
105
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000106SkCanvas* SkSurface::getCanvas() {
107 return asSB(this)->getCachedCanvas();
reed@google.com889b09e2012-07-27 21:10:42 +0000108}
109
junov@chromium.org5ee449a2013-04-12 20:20:50 +0000110SkImage* SkSurface::newImageSnapshot() {
reed@google.com97af1a62012-08-28 12:19:02 +0000111 SkImage* image = asSB(this)->getCachedImage();
112 SkSafeRef(image); // the caller will call unref() to balance this
113 return image;
reed@google.com889b09e2012-07-27 21:10:42 +0000114}
115
reed@google.com2bd8b812013-11-01 13:46:54 +0000116SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +0000117 return asSB(this)->onNewSurface(info);
reed@google.com889b09e2012-07-27 21:10:42 +0000118}
119
120void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
121 const SkPaint* paint) {
122 return asSB(this)->onDraw(canvas, x, y, paint);
123}
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000124
125const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
126 return this->getCanvas()->peekPixels(info, rowBytes);
127}