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 SkFlatData* SkFlatData::Create(SkFlatController* controller, const void* obj,
     98         int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*)) {
     99     // a buffer of 256 bytes should be sufficient for most paints, regions,
    100     // and matrices.
    101     intptr_t storage[256];
    102     SkOrderedWriteBuffer buffer(256, storage, sizeof(storage));
    103 
    104     buffer.setBitmapHeap(controller->getBitmapHeap());
    105     buffer.setTypefaceRecorder(controller->getTypefaceSet());
    106     buffer.setNamedFactoryRecorder(controller->getNamedFactorySet());
    107     buffer.setFlags(controller->getWriteBufferFlags());
    108 
    109     flattenProc(buffer, obj);
    110     uint32_t size = buffer.size();
    111     SkASSERT(SkIsAlign4(size));
    112 
    113     /**
    114      *  Allocate enough memory to hold
    115      *  1. SkFlatData struct
    116      *  2. flattenProc's data (4-byte aligned)
    117      *  3. 4-byte sentinel
    118      */
    119     size_t allocSize = sizeof(SkFlatData) + size + sizeof(uint32_t);
    120     SkFlatData* result = (SkFlatData*) controller->allocThrow(allocSize);
    121 
    122     result->fIndex = index;
    123     result->setTopBotUnwritten();
    124     result->fFlatSize = size;
    125 
    126     // put the serialized contents into the data section of the new allocation
    127     buffer.writeToMemory(result->data());
    128     result->fChecksum = SkChecksum::Compute(result->data32(), size);
    129     result->setSentinelAsCandidate();
    130     return result;
    131 }
    132 
    133 void SkFlatData::unflatten(void* result,
    134         void (*unflattenProc)(SkOrderedReadBuffer&, void*),
    135         SkBitmapHeap* bitmapHeap,
    136         SkTypefacePlayback* facePlayback) const {
    137 
    138     SkOrderedReadBuffer buffer(this->data(), fFlatSize);
    139 
    140     if (bitmapHeap) {
    141         buffer.setBitmapStorage(bitmapHeap);
    142     }
    143     if (facePlayback) {
    144         facePlayback->setupBuffer(buffer);
    145     }
    146 
    147     unflattenProc(buffer, result);
    148     SkASSERT(fFlatSize == (int32_t)buffer.offset());
    149 }
    150