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