blob: 3a28e421a880df9ff6ae9962aa504c6bd63bb040 [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
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000046 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
reed@google.com97af1a62012-08-28 12:19:02 +000047
bsalomon49f085d2014-09-05 13:34:00 -070048 if (fCachedImage) {
reed@google.com97af1a62012-08-28 12:19:02 +000049 // the surface may need to fork its backend, if its sharing it with
50 // the cached image. Note: we only call if there is an outstanding owner
51 // on the image (besides us).
bungeman@google.comf64c6842013-07-19 23:18:52 +000052 if (!fCachedImage->unique()) {
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000053 this->onCopyOnWrite(mode);
reed@google.com97af1a62012-08-28 12:19:02 +000054 }
55
56 // regardless of copy-on-write, we must drop our cached image now, so
57 // that the next request will get our new contents.
58 fCachedImage->unref();
59 fCachedImage = NULL;
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000060 } else if (kDiscard_ContentChangeMode == mode) {
61 this->onDiscard();
reed@google.com97af1a62012-08-28 12:19:02 +000062 }
63}
64
65uint32_t SkSurface_Base::newGenerationID() {
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000066 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
reed@google.com97af1a62012-08-28 12:19:02 +000067 static int32_t gID;
68 return sk_atomic_inc(&gID) + 1;
69}
70
reed@google.com889b09e2012-07-27 21:10:42 +000071static SkSurface_Base* asSB(SkSurface* surface) {
72 return static_cast<SkSurface_Base*>(surface);
73}
74
75///////////////////////////////////////////////////////////////////////////////
76
77SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
reed@google.com1360c522014-01-08 21:25:26 +000078 SkASSERT(fWidth >= 0);
79 SkASSERT(fHeight >= 0);
80 fGenerationID = 0;
81}
82
reede5ea5002014-09-03 11:54:58 -070083SkSurface::SkSurface(const SkImageInfo& info) : fWidth(info.width()), fHeight(info.height()) {
reed@google.com1360c522014-01-08 21:25:26 +000084 SkASSERT(fWidth >= 0);
85 SkASSERT(fHeight >= 0);
reed@google.com889b09e2012-07-27 21:10:42 +000086 fGenerationID = 0;
87}
88
reed@google.com97af1a62012-08-28 12:19:02 +000089uint32_t SkSurface::generationID() {
90 if (0 == fGenerationID) {
91 fGenerationID = asSB(this)->newGenerationID();
92 }
93 return fGenerationID;
94}
95
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000096void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
97 asSB(this)->aboutToDraw(mode);
reed@google.com97af1a62012-08-28 12:19:02 +000098}
99
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000100SkCanvas* SkSurface::getCanvas() {
101 return asSB(this)->getCachedCanvas();
reed@google.com889b09e2012-07-27 21:10:42 +0000102}
103
junov@chromium.org5ee449a2013-04-12 20:20:50 +0000104SkImage* SkSurface::newImageSnapshot() {
reed@google.com97af1a62012-08-28 12:19:02 +0000105 SkImage* image = asSB(this)->getCachedImage();
106 SkSafeRef(image); // the caller will call unref() to balance this
107 return image;
reed@google.com889b09e2012-07-27 21:10:42 +0000108}
109
reed@google.com2bd8b812013-11-01 13:46:54 +0000110SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +0000111 return asSB(this)->onNewSurface(info);
reed@google.com889b09e2012-07-27 21:10:42 +0000112}
113
114void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
115 const SkPaint* paint) {
116 return asSB(this)->onDraw(canvas, x, y, paint);
117}
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000118
119const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
120 return this->getCanvas()->peekPixels(info, rowBytes);
121}