Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SamplePipeControllers.h"
      9 
     10 #include "SkBitmapDevice.h"
     11 #include "SkCanvas.h"
     12 #include "SkGPipe.h"
     13 #include "SkMatrix.h"
     14 
     15 PipeController::PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc)
     16 :fReader(target) {
     17     fBlock = NULL;
     18     fBlockSize = fBytesWritten = 0;
     19     fReader.setBitmapDecoder(proc);
     20 }
     21 
     22 PipeController::~PipeController() {
     23     sk_free(fBlock);
     24 }
     25 
     26 void* PipeController::requestBlock(size_t minRequest, size_t *actual) {
     27     sk_free(fBlock);
     28     fBlockSize = minRequest * 4;
     29     fBlock = sk_malloc_throw(fBlockSize);
     30     fBytesWritten = 0;
     31     *actual = fBlockSize;
     32     return fBlock;
     33 }
     34 
     35 void PipeController::notifyWritten(size_t bytes) {
     36     fStatus = fReader.playback(this->getData(), bytes);
     37     SkASSERT(SkGPipeReader::kError_Status != fStatus);
     38     fBytesWritten += bytes;
     39 }
     40 
     41 ////////////////////////////////////////////////////////////////////////////////
     42 
     43 TiledPipeController::TiledPipeController(const SkBitmap& bitmap,
     44                                          SkPicture::InstallPixelRefProc proc,
     45                                          const SkMatrix* initial)
     46 : INHERITED(NULL, proc) {
     47     int32_t top = 0;
     48     int32_t bottom;
     49     int32_t height = bitmap.height() / NumberOfTiles;
     50     SkIRect rect;
     51     for (int i = 0; i < NumberOfTiles; i++) {
     52         bottom = i + 1 == NumberOfTiles ? bitmap.height() : top + height;
     53         rect.setLTRB(0, top, bitmap.width(), bottom);
     54         top = bottom;
     55 
     56         SkDEBUGCODE(bool extracted = )bitmap.extractSubset(&fBitmaps[i], rect);
     57         SkASSERT(extracted);
     58         SkBaseDevice* device = new SkBitmapDevice(fBitmaps[i]);
     59         SkCanvas* canvas = new SkCanvas(device);
     60         device->unref();
     61         if (initial != NULL) {
     62             canvas->setMatrix(*initial);
     63         }
     64         canvas->translate(SkIntToScalar(-rect.left()),
     65                           SkIntToScalar(-rect.top()));
     66         if (0 == i) {
     67             fReader.setCanvas(canvas);
     68         } else {
     69             fReaders[i - 1].setCanvas(canvas);
     70             fReaders[i - 1].setBitmapDecoder(proc);
     71         }
     72         canvas->unref();
     73     }
     74 }
     75 
     76 void TiledPipeController::notifyWritten(size_t bytes) {
     77     for (int i = 0; i < NumberOfTiles - 1; i++) {
     78         fReaders[i].playback(this->getData(), bytes);
     79     }
     80     this->INHERITED::notifyWritten(bytes);
     81 }
     82 
     83 ////////////////////////////////////////////////////////////////////////////////
     84 
     85 ThreadSafePipeController::ThreadSafePipeController(int numberOfReaders)
     86 : fAllocator(kMinBlockSize)
     87 , fNumberOfReaders(numberOfReaders) {
     88     fBlock = NULL;
     89     fBytesWritten = 0;
     90 }
     91 
     92 void* ThreadSafePipeController::requestBlock(size_t minRequest, size_t *actual) {
     93     if (fBlock) {
     94         // Save the previous block for later
     95         PipeBlock previousBloc(fBlock, fBytesWritten);
     96         fBlockList.push(previousBloc);
     97     }
     98     int32_t blockSize = SkMax32(SkToS32(minRequest), kMinBlockSize);
     99     fBlock = fAllocator.allocThrow(blockSize);
    100     fBytesWritten = 0;
    101     *actual = blockSize;
    102     return fBlock;
    103 }
    104 
    105 void ThreadSafePipeController::notifyWritten(size_t bytes) {
    106     fBytesWritten += bytes;
    107 }
    108 
    109 void ThreadSafePipeController::draw(SkCanvas* target) {
    110     SkGPipeReader reader(target);
    111     for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
    112         reader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fBytes);
    113     }
    114 
    115     if (fBlock) {
    116         reader.playback(fBlock, fBytesWritten);
    117     }
    118 }
    119