aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkRegionPriv.h
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
commit8a1c16ff38322f0210116fa7293eb8817c7e477e (patch)
treefe40e07f6c8983318a2f79032b9a706ede1090c1 /src/core/SkRegionPriv.h
parent2559c629078f738ac37095d896d580b681ac6a30 (diff)
grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkRegionPriv.h')
-rw-r--r--src/core/SkRegionPriv.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/core/SkRegionPriv.h b/src/core/SkRegionPriv.h
new file mode 100644
index 0000000000..70f882835e
--- /dev/null
+++ b/src/core/SkRegionPriv.h
@@ -0,0 +1,89 @@
+/* libs/corecg/SkRegionPriv.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkRegionPriv_DEFINED
+#define SkRegionPriv_DEFINED
+
+#include "SkRegion.h"
+#include "SkThread.h"
+
+#define assert_sentinel(value, isSentinel) \
+ SkASSERT(((value) == SkRegion::kRunTypeSentinel) == isSentinel)
+
+//SkDEBUGCODE(extern int32_t gRgnAllocCounter;)
+
+struct SkRegion::RunHead {
+ int32_t fRefCnt;
+ int32_t fRunCount;
+
+ static RunHead* Alloc(int count)
+ {
+ //SkDEBUGCODE(sk_atomic_inc(&gRgnAllocCounter);)
+ //SkDEBUGF(("************** gRgnAllocCounter::alloc %d\n", gRgnAllocCounter));
+
+ SkASSERT(count >= SkRegion::kRectRegionRuns);
+
+ RunHead* head = (RunHead*)sk_malloc_throw(sizeof(RunHead) + count * sizeof(RunType));
+ head->fRefCnt = 1;
+ head->fRunCount = count;
+ return head;
+ }
+
+ bool isComplex() const
+ {
+ return this != SkRegion_gEmptyRunHeadPtr && this != SkRegion_gRectRunHeadPtr;
+ }
+
+ SkRegion::RunType* writable_runs()
+ {
+ SkASSERT(this->isComplex());
+ SkASSERT(fRefCnt == 1);
+ return (SkRegion::RunType*)(this + 1);
+ }
+ const SkRegion::RunType* readonly_runs() const
+ {
+ SkASSERT(this->isComplex());
+ return (const SkRegion::RunType*)(this + 1);
+ }
+
+ RunHead* ensureWritable()
+ {
+ SkASSERT(this->isComplex());
+
+ RunHead* writable = this;
+ if (fRefCnt > 1)
+ {
+ // We need to alloc & copy the current region before we call
+ // sk_atomic_dec because it could be freed in the meantime,
+ // otherwise.
+ writable = Alloc(fRunCount);
+ memcpy(writable->writable_runs(), this->readonly_runs(),
+ fRunCount * sizeof(RunType));
+
+ // fRefCount might have changed since we last checked.
+ // If we own the last reference at this point, we need to
+ // free the memory.
+ if (sk_atomic_dec(&fRefCnt) == 1)
+ {
+ sk_free(this);
+ }
+ }
+ return writable;
+ }
+};
+
+#endif