180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2009 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorTable.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTemplates.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(SkColorTable) 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::SkColorTable(int count) 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : f16BitCache(NULL), fFlags(0) 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count < 0) 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count = 0; 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else if (count > 256) 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count = 256; 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount = SkToU16(count); 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor)); 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(fColors, 0, count * sizeof(SkPMColor)); 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(fColorLockCount = 0;) 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(f16BitCacheLockCount = 0;) 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// As copy constructor is hidden in the class hierarchy, we need to call 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// default constructor explicitly to suppress a compiler warning. 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::SkColorTable(const SkColorTable& src) : INHERITED() { 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru f16BitCache = NULL; 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = src.fFlags; 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int count = src.count(); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount = SkToU16(count); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColors = reinterpret_cast<SkPMColor*>( 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_malloc_throw(count * sizeof(SkPMColor))); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(fColors, src.fColors, count * sizeof(SkPMColor)); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(fColorLockCount = 0;) 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(f16BitCacheLockCount = 0;) 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::SkColorTable(const SkPMColor colors[], int count) 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : f16BitCache(NULL), fFlags(0) 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count < 0) 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count = 0; 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else if (count > 256) 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count = 256; 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount = SkToU16(count); 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColors = reinterpret_cast<SkPMColor*>( 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_malloc_throw(count * sizeof(SkPMColor))); 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (colors) 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(fColors, colors, count * sizeof(SkPMColor)); 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(fColorLockCount = 0;) 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(f16BitCacheLockCount = 0;) 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::~SkColorTable() 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fColorLockCount == 0); 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(f16BitCacheLockCount == 0); 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(fColors); 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(f16BitCache); 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorTable::setFlags(unsigned flags) 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = SkToU8(flags); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorTable::unlockColors(bool changed) 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fColorLockCount != 0); 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(sk_atomic_dec(&fColorLockCount);) 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (changed) 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->inval16BitCache(); 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorTable::inval16BitCache() 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(f16BitCacheLockCount == 0); 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (f16BitCache) 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(f16BitCache); 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru f16BitCache = NULL; 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h" 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count) 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (--count >= 0) 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *dst++ = SkPixel32ToPixel16_ToU16(*src++); 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst uint16_t* SkColorTable::lock16BitCache() 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fFlags & kColorsAreOpaque_Flag) 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (f16BitCache == NULL) // build the cache 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t)); 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru build_16bitcache(f16BitCache, fColors, fCount); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else // our colors have alpha, so no cache 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->inval16BitCache(); 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (f16BitCache) 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(f16BitCache); 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru f16BitCache = NULL; 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(f16BitCacheLockCount += 1); 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return f16BitCache; 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorTable::setIsOpaque(bool isOpaque) { 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isOpaque) { 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags |= kColorsAreOpaque_Flag; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags &= ~kColorsAreOpaque_Flag; 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) { 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru f16BitCache = NULL; 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(fColorLockCount = 0;) 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(f16BitCacheLockCount = 0;) 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = buffer.readUInt(); 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount = buffer.getArrayCount(); 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor)); 149d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkDEBUGCODE(const uint32_t countRead =) buffer.readColorArray(fColors); 150d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEBUG 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)fCount <= 256); 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(countRead == fCount); 153d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const { 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.writeUInt(fFlags); 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.writeColorArray(fColors, fCount); 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 160