blob: 648643f7a0ffcd28f4caf09d0599af9e90db151b [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#ifndef SkRegionPriv_DEFINED
11#define SkRegionPriv_DEFINED
12
13#include "SkRegion.h"
14#include "SkThread.h"
15
16#define assert_sentinel(value, isSentinel) \
17 SkASSERT(((value) == SkRegion::kRunTypeSentinel) == isSentinel)
18
19//SkDEBUGCODE(extern int32_t gRgnAllocCounter;)
20
21struct SkRegion::RunHead {
22 int32_t fRefCnt;
23 int32_t fRunCount;
24
25 static RunHead* Alloc(int count)
26 {
27 //SkDEBUGCODE(sk_atomic_inc(&gRgnAllocCounter);)
28 //SkDEBUGF(("************** gRgnAllocCounter::alloc %d\n", gRgnAllocCounter));
29
30 SkASSERT(count >= SkRegion::kRectRegionRuns);
31
32 RunHead* head = (RunHead*)sk_malloc_throw(sizeof(RunHead) + count * sizeof(RunType));
33 head->fRefCnt = 1;
34 head->fRunCount = count;
35 return head;
36 }
37
38 bool isComplex() const
39 {
40 return this != SkRegion_gEmptyRunHeadPtr && this != SkRegion_gRectRunHeadPtr;
41 }
42
43 SkRegion::RunType* writable_runs()
44 {
45 SkASSERT(this->isComplex());
46 SkASSERT(fRefCnt == 1);
47 return (SkRegion::RunType*)(this + 1);
48 }
49 const SkRegion::RunType* readonly_runs() const
50 {
51 SkASSERT(this->isComplex());
52 return (const SkRegion::RunType*)(this + 1);
53 }
54
55 RunHead* ensureWritable()
56 {
57 SkASSERT(this->isComplex());
58
59 RunHead* writable = this;
60 if (fRefCnt > 1)
61 {
62 // We need to alloc & copy the current region before we call
63 // sk_atomic_dec because it could be freed in the meantime,
64 // otherwise.
65 writable = Alloc(fRunCount);
66 memcpy(writable->writable_runs(), this->readonly_runs(),
67 fRunCount * sizeof(RunType));
68
69 // fRefCount might have changed since we last checked.
70 // If we own the last reference at this point, we need to
71 // free the memory.
72 if (sk_atomic_dec(&fRefCnt) == 1)
73 {
74 sk_free(this);
75 }
76 }
77 return writable;
78 }
79};
80
81#endif