예제 #1
0
BitmapHolder::BitmapHolder(SkReader32* reader, uint32_t op32,
                           SkGPipeState* state) {
    const unsigned flags = state->getFlags();
    const unsigned index = DrawOp_unpackData(op32);
    if (shouldFlattenBitmaps(flags)) {
        fHeapEntry = NULL;
        fBitmap = state->getBitmap(index);
    } else {
        SkBitmapHeapEntry* entry = state->getSharedHeap()->getEntry(index);
        if (SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)) {
            // Make a shallow copy for thread safety. Each thread will point to the same SkPixelRef,
            // which is thread safe.
            fBitmapStorage = *entry->getBitmap();
            fBitmap = &fBitmapStorage;
            // Release the ref on the bitmap now, since we made our own copy.
            entry->releaseRef();
            fHeapEntry = NULL;
        } else {
            SkASSERT(!shouldFlattenBitmaps(flags));
            SkASSERT(!SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag));
            fHeapEntry = entry;
            fBitmap = fHeapEntry->getBitmap();
        }
    }
}
예제 #2
0
SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
                             SkWriter32* writer, uint32_t flags,
                             uint32_t width, uint32_t height)
    : SkCanvas(width, height)
    , fFactorySet(is_cross_process(flags) ? SkNEW(SkNamedFactorySet) : NULL)
    , fWriter(*writer)
    , fFlags(flags)
    , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, is_cross_process(flags))
    , fFlatDictionary(&fFlattenableHeap)
{
    fController = controller;
    fDone = false;
    fBlockSize = 0; // need first block from controller
    fBytesNotified = 0;
    sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));

    // Tell the reader the appropriate flags to use.
    if (this->needOpBytes()) {
        this->writeOp(kReportFlags_DrawOp, fFlags, 0);
    }

    if (shouldFlattenBitmaps(flags)) {
        fBitmapShuttle.reset(SkNEW_ARGS(BitmapShuttle, (this)));
        fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, (fBitmapShuttle.get(), BITMAPS_TO_KEEP));
    } else {
        fBitmapHeap = SkNEW_ARGS(SkBitmapHeap,
                                 (BITMAPS_TO_KEEP, controller->numberOfReaders()));
        if (this->needOpBytes(sizeof(void*))) {
            this->writeOp(kShareBitmapHeap_DrawOp);
            fWriter.writePtr(static_cast<void*>(fBitmapHeap));
        }
    }
    fFlattenableHeap.setBitmapStorage(fBitmapHeap);
    this->doNotify();
}
예제 #3
0
 /**
  * Add a bitmap to the array of bitmaps, or replace an existing one.
  * This is only used when in cross process mode without a shared heap.
  */
 void addBitmap(int index) {
     SkASSERT(shouldFlattenBitmaps(fFlags));
     SkBitmap* bm;
     if(fBitmaps.count() == index) {
         bm = SkNEW(SkBitmap);
         *fBitmaps.append() = bm;
     } else {
         bm = fBitmaps[index];
     }
     fReader->readBitmap(bm);
 }
예제 #4
0
bool SkGPipeCanvas::shuttleBitmap(const SkBitmap& bm, int32_t slot) {
    SkASSERT(shouldFlattenBitmaps(fFlags));
    SkWriteBuffer buffer;
    buffer.setNamedFactoryRecorder(fFactorySet);
    buffer.writeBitmap(bm);
    this->flattenFactoryNames();
    size_t size = buffer.bytesWritten();
    if (this->needOpBytes(size)) {
        this->writeOp(kDef_Bitmap_DrawOp, 0, slot);
        void* dst = static_cast<void*>(fWriter.reserve(size));
        buffer.writeToMemory(dst);
        return true;
    }
    return false;
}
예제 #5
0
    /**
     *  Called when nothing else is to be written to the stream. Any repeated
     *  calls are ignored.
     *
     *  @param notifyReaders Whether to send a message to the reader(s) that
     *      the writer is through sending commands. Should generally be true,
     *      unless there is an error which prevents further messages from
     *      being sent.
     */
    void finish(bool notifyReaders) {
        if (fDone) {
            return;
        }
        if (notifyReaders && this->needOpBytes()) {
            this->writeOp(kDone_DrawOp);
            this->doNotify();
        }
        if (shouldFlattenBitmaps(fFlags)) {
            // The following circular references exist:
            // fFlattenableHeap -> fWriteBuffer -> fBitmapStorage -> fExternalStorage -> fCanvas
            // fBitmapHeap -> fExternalStorage -> fCanvas
            // fFlattenableHeap -> fBitmapStorage -> fExternalStorage -> fCanvas

            // Break them all by destroying the final link to this SkGPipeCanvas.
            fBitmapShuttle->removeCanvas();
        }
        fDone = true;
    }
예제 #6
0
    void updateReader() {
        if (NULL == fReader) {
            return;
        }
        bool crossProcess = SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag);
        fReader->setFlags(SkSetClearMask(fReader->getFlags(), crossProcess,
                                         SkReadBuffer::kCrossProcess_Flag));
        if (crossProcess) {
            fReader->setFactoryArray(&fFactoryArray);
        } else {
            fReader->setFactoryArray(NULL);
        }

        if (shouldFlattenBitmaps(fFlags)) {
            fReader->setBitmapStorage(this);
        } else {
            fReader->setBitmapStorage(fSharedHeap);
        }
    }
예제 #7
0
 /**
  * Access the shared heap. Only used in the case when bitmaps are not
  * flattened.
  */
 SkBitmapHeap* getSharedHeap() const {
     SkASSERT(!shouldFlattenBitmaps(fFlags));
     return fSharedHeap;
 }
예제 #8
0
 void setSharedHeap(SkBitmapHeap* heap) {
     SkASSERT(!shouldFlattenBitmaps(fFlags) || NULL == heap);
     SkRefCnt_SafeAssign(fSharedHeap, heap);
     this->updateReader();
 }
예제 #9
0
 /**
  * Override of SkBitmapHeapReader, so that SkReadBuffer can use
  * these SkBitmaps for bitmap shaders. Used only in cross process mode
  * without a shared heap.
  */
 SkBitmap* getBitmap(int32_t index) const override {
     SkASSERT(shouldFlattenBitmaps(fFlags));
     return fBitmaps[index];
 }