Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      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 #include "SkPictureFlat.h"
      9 
     10 #include "SkChecksum.h"
     11 #include "SkColorFilter.h"
     12 #include "SkDrawLooper.h"
     13 #include "SkMaskFilter.h"
     14 #include "SkRasterizer.h"
     15 #include "SkShader.h"
     16 #include "SkTypeface.h"
     17 #include "SkXfermode.h"
     18 
     19 SK_DEFINE_INST_COUNT(SkFlatController)
     20 
     21 ///////////////////////////////////////////////////////////////////////////////
     22 
     23 SkTypefacePlayback::SkTypefacePlayback() : fCount(0), fArray(NULL) {}
     24 
     25 SkTypefacePlayback::~SkTypefacePlayback() {
     26     this->reset(NULL);
     27 }
     28 
     29 void SkTypefacePlayback::reset(const SkRefCntSet* rec) {
     30     for (int i = 0; i < fCount; i++) {
     31         SkASSERT(fArray[i]);
     32         fArray[i]->unref();
     33     }
     34     SkDELETE_ARRAY(fArray);
     35 
     36     if (rec!= NULL && rec->count() > 0) {
     37         fCount = rec->count();
     38         fArray = SkNEW_ARRAY(SkRefCnt*, fCount);
     39         rec->copyToArray(fArray);
     40         for (int i = 0; i < fCount; i++) {
     41             fArray[i]->ref();
     42         }
     43     } else {
     44         fCount = 0;
     45         fArray = NULL;
     46     }
     47 }
     48 
     49 void SkTypefacePlayback::setCount(int count) {
     50     this->reset(NULL);
     51 
     52     fCount = count;
     53     fArray = SkNEW_ARRAY(SkRefCnt*, count);
     54     sk_bzero(fArray, count * sizeof(SkRefCnt*));
     55 }
     56 
     57 SkRefCnt* SkTypefacePlayback::set(int index, SkRefCnt* obj) {
     58     SkASSERT((unsigned)index < (unsigned)fCount);
     59     SkRefCnt_SafeAssign(fArray[index], obj);
     60     return obj;
     61 }
     62 
     63 ///////////////////////////////////////////////////////////////////////////////
     64 
     65 SkFlatController::SkFlatController()
     66 : fBitmapHeap(NULL)
     67 , fTypefaceSet(NULL)
     68 , fTypefacePlayback(NULL)
     69 , fFactorySet(NULL)
     70 , fWriteBufferFlags(0) {}
     71 
     72 SkFlatController::~SkFlatController() {
     73     SkSafeUnref(fBitmapHeap);
     74     SkSafeUnref(fTypefaceSet);
     75     SkSafeUnref(fFactorySet);
     76 }
     77 
     78 void SkFlatController::setBitmapHeap(SkBitmapHeap* heap) {
     79     SkRefCnt_SafeAssign(fBitmapHeap, heap);
     80 }
     81 
     82 void SkFlatController::setTypefaceSet(SkRefCntSet *set) {
     83     SkRefCnt_SafeAssign(fTypefaceSet, set);
     84 }
     85 
     86 void SkFlatController::setTypefacePlayback(SkTypefacePlayback* playback) {
     87     fTypefacePlayback = playback;
     88 }
     89 
     90 SkNamedFactorySet* SkFlatController::setNamedFactorySet(SkNamedFactorySet* set) {
     91     SkRefCnt_SafeAssign(fFactorySet, set);
     92     return set;
     93 }
     94 
     95 ///////////////////////////////////////////////////////////////////////////////
     96 
     97 void SkFlatData::stampHeaderAndSentinel(int index, int32_t size) {
     98     fIndex    = index;
     99     fFlatSize = size;
    100     fChecksum = SkChecksum::Compute(this->data32(), size);
    101     this->setTopBotUnwritten();
    102     this->setSentinelAsCandidate();
    103 }
    104 
    105 SkFlatData* SkFlatData::Create(SkFlatController* controller, const void* obj,
    106         int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*)) {
    107     // a buffer of 256 bytes should be sufficient for most paints, regions,
    108     // and matrices.
    109     intptr_t storage[256];
    110     SkOrderedWriteBuffer buffer(256, storage, sizeof(storage));
    111 
    112     buffer.setBitmapHeap(controller->getBitmapHeap());
    113     buffer.setTypefaceRecorder(controller->getTypefaceSet());
    114     buffer.setNamedFactoryRecorder(controller->getNamedFactorySet());
    115     buffer.setFlags(controller->getWriteBufferFlags());
    116 
    117     flattenProc(buffer, obj);
    118     uint32_t size = buffer.size();
    119     SkASSERT(SkIsAlign4(size));
    120 
    121     /**
    122      *  Allocate enough memory to hold
    123      *  1. SkFlatData struct
    124      *  2. flattenProc's data (4-byte aligned)
    125      *  3. 4-byte sentinel
    126      */
    127     size_t allocSize = sizeof(SkFlatData) + size + sizeof(uint32_t);
    128     SkFlatData* result = (SkFlatData*) controller->allocThrow(allocSize);
    129 
    130     // put the serialized contents into the data section of the new allocation
    131     buffer.writeToMemory(result->data());
    132     result->stampHeaderAndSentinel(index, size);
    133     return result;
    134 }
    135 
    136 void SkFlatData::unflatten(void* result,
    137         void (*unflattenProc)(SkOrderedReadBuffer&, void*),
    138         SkBitmapHeap* bitmapHeap,
    139         SkTypefacePlayback* facePlayback) const {
    140 
    141     SkOrderedReadBuffer buffer(this->data(), fFlatSize);
    142 
    143     if (bitmapHeap) {
    144         buffer.setBitmapStorage(bitmapHeap);
    145     }
    146     if (facePlayback) {
    147         facePlayback->setupBuffer(buffer);
    148     }
    149 
    150     unflattenProc(buffer, result);
    151     SkASSERT(fFlatSize == (int32_t)buffer.offset());
    152 }
    153