epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | |
reed@android.com | a6260ff | 2009-05-04 18:52:54 +0000 | [diff] [blame] | 2 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 3 | * Copyright 2009 The Android Open Source Project |
reed@android.com | a6260ff | 2009-05-04 18:52:54 +0000 | [diff] [blame] | 4 | * |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
reed@android.com | a6260ff | 2009-05-04 18:52:54 +0000 | [diff] [blame] | 7 | */ |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 8 | |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 9 | |
djsollen@google.com | 64a0ec3 | 2012-06-12 15:17:27 +0000 | [diff] [blame] | 10 | #include "SkColorTable.h" |
djsollen@google.com | c73dd5c | 2012-08-07 15:54:32 +0000 | [diff] [blame] | 11 | #include "SkFlattenableBuffers.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 12 | #include "SkStream.h" |
| 13 | #include "SkTemplates.h" |
| 14 | |
robertphillips@google.com | 0456e0b | 2012-06-27 14:03:26 +0000 | [diff] [blame] | 15 | SK_DEFINE_INST_COUNT(SkColorTable) |
| 16 | |
reed@google.com | 2999f78 | 2012-06-19 15:27:46 +0000 | [diff] [blame] | 17 | // As copy constructor is hidden in the class hierarchy, we need to call |
| 18 | // default constructor explicitly to suppress a compiler warning. |
| 19 | SkColorTable::SkColorTable(const SkColorTable& src) : INHERITED() { |
weita@google.com | f9ab99a | 2009-05-03 18:23:30 +0000 | [diff] [blame] | 20 | f16BitCache = NULL; |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 21 | fAlphaType = src.fAlphaType; |
weita@google.com | f9ab99a | 2009-05-03 18:23:30 +0000 | [diff] [blame] | 22 | int count = src.count(); |
| 23 | fCount = SkToU16(count); |
reed@android.com | a6260ff | 2009-05-04 18:52:54 +0000 | [diff] [blame] | 24 | fColors = reinterpret_cast<SkPMColor*>( |
| 25 | sk_malloc_throw(count * sizeof(SkPMColor))); |
weita@google.com | f9ab99a | 2009-05-03 18:23:30 +0000 | [diff] [blame] | 26 | memcpy(fColors, src.fColors, count * sizeof(SkPMColor)); |
| 27 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 28 | SkDEBUGCODE(fColorLockCount = 0;) |
| 29 | SkDEBUGCODE(f16BitCacheLockCount = 0;) |
| 30 | } |
| 31 | |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 32 | SkColorTable::SkColorTable(const SkPMColor colors[], int count, SkAlphaType at) |
| 33 | : f16BitCache(NULL), fAlphaType(SkToU8(at)) |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 34 | { |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 35 | SkASSERT(0 == count || NULL != colors); |
| 36 | |
| 37 | if (count < 0) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 38 | count = 0; |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 39 | } else if (count > 256) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 40 | count = 256; |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 41 | } |
weita@google.com | f9ab99a | 2009-05-03 18:23:30 +0000 | [diff] [blame] | 42 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 43 | fCount = SkToU16(count); |
reed@android.com | a6260ff | 2009-05-04 18:52:54 +0000 | [diff] [blame] | 44 | fColors = reinterpret_cast<SkPMColor*>( |
| 45 | sk_malloc_throw(count * sizeof(SkPMColor))); |
weita@google.com | f9ab99a | 2009-05-03 18:23:30 +0000 | [diff] [blame] | 46 | |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 47 | memcpy(fColors, colors, count * sizeof(SkPMColor)); |
weita@google.com | f9ab99a | 2009-05-03 18:23:30 +0000 | [diff] [blame] | 48 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 49 | SkDEBUGCODE(fColorLockCount = 0;) |
| 50 | SkDEBUGCODE(f16BitCacheLockCount = 0;) |
| 51 | } |
| 52 | |
| 53 | SkColorTable::~SkColorTable() |
| 54 | { |
| 55 | SkASSERT(fColorLockCount == 0); |
| 56 | SkASSERT(f16BitCacheLockCount == 0); |
| 57 | |
| 58 | sk_free(fColors); |
| 59 | sk_free(f16BitCache); |
| 60 | } |
| 61 | |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 62 | void SkColorTable::unlockColors() { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 63 | SkASSERT(fColorLockCount != 0); |
djsollen@google.com | c9ab987 | 2012-08-29 18:52:07 +0000 | [diff] [blame] | 64 | SkDEBUGCODE(sk_atomic_dec(&fColorLockCount);) |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | #include "SkColorPriv.h" |
| 68 | |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 69 | static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], |
| 70 | int count) { |
| 71 | while (--count >= 0) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 72 | *dst++ = SkPixel32ToPixel16_ToU16(*src++); |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 73 | } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 74 | } |
| 75 | |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 76 | const uint16_t* SkColorTable::lock16BitCache() { |
| 77 | if (this->isOpaque() && NULL == f16BitCache) { |
| 78 | f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t)); |
| 79 | build_16bitcache(f16BitCache, fColors, fCount); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | SkDEBUGCODE(f16BitCacheLockCount += 1); |
| 83 | return f16BitCache; |
| 84 | } |
| 85 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 86 | /////////////////////////////////////////////////////////////////////////////// |
| 87 | |
| 88 | SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) { |
| 89 | f16BitCache = NULL; |
| 90 | SkDEBUGCODE(fColorLockCount = 0;) |
| 91 | SkDEBUGCODE(f16BitCacheLockCount = 0;) |
| 92 | |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 93 | fAlphaType = SkToU8(buffer.readUInt()); |
djsollen@google.com | c73dd5c | 2012-08-07 15:54:32 +0000 | [diff] [blame] | 94 | fCount = buffer.getArrayCount(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 95 | fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor)); |
bsalomon@google.com | 57313f6 | 2013-01-07 17:35:10 +0000 | [diff] [blame] | 96 | SkDEBUGCODE(const uint32_t countRead =) buffer.readColorArray(fColors); |
| 97 | #ifdef SK_DEBUG |
djsollen@google.com | c73dd5c | 2012-08-07 15:54:32 +0000 | [diff] [blame] | 98 | SkASSERT((unsigned)fCount <= 256); |
| 99 | SkASSERT(countRead == fCount); |
bsalomon@google.com | 57313f6 | 2013-01-07 17:35:10 +0000 | [diff] [blame] | 100 | #endif |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | void SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const { |
reed@google.com | 0a6151d | 2013-10-10 14:44:56 +0000 | [diff] [blame^] | 104 | buffer.writeUInt(fAlphaType); |
djsollen@google.com | c73dd5c | 2012-08-07 15:54:32 +0000 | [diff] [blame] | 105 | buffer.writeColorArray(fColors, fCount); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 106 | } |