michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #include "SamplePipeControllers.h" michael@0: michael@0: #include "SkBitmapDevice.h" michael@0: #include "SkCanvas.h" michael@0: #include "SkGPipe.h" michael@0: #include "SkMatrix.h" michael@0: michael@0: PipeController::PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc) michael@0: :fReader(target) { michael@0: fBlock = NULL; michael@0: fBlockSize = fBytesWritten = 0; michael@0: fReader.setBitmapDecoder(proc); michael@0: } michael@0: michael@0: PipeController::~PipeController() { michael@0: sk_free(fBlock); michael@0: } michael@0: michael@0: void* PipeController::requestBlock(size_t minRequest, size_t *actual) { michael@0: sk_free(fBlock); michael@0: fBlockSize = minRequest * 4; michael@0: fBlock = sk_malloc_throw(fBlockSize); michael@0: fBytesWritten = 0; michael@0: *actual = fBlockSize; michael@0: return fBlock; michael@0: } michael@0: michael@0: void PipeController::notifyWritten(size_t bytes) { michael@0: fStatus = fReader.playback(this->getData(), bytes); michael@0: SkASSERT(SkGPipeReader::kError_Status != fStatus); michael@0: fBytesWritten += bytes; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: TiledPipeController::TiledPipeController(const SkBitmap& bitmap, michael@0: SkPicture::InstallPixelRefProc proc, michael@0: const SkMatrix* initial) michael@0: : INHERITED(NULL, proc) { michael@0: int32_t top = 0; michael@0: int32_t bottom; michael@0: int32_t height = bitmap.height() / NumberOfTiles; michael@0: SkIRect rect; michael@0: for (int i = 0; i < NumberOfTiles; i++) { michael@0: bottom = i + 1 == NumberOfTiles ? bitmap.height() : top + height; michael@0: rect.setLTRB(0, top, bitmap.width(), bottom); michael@0: top = bottom; michael@0: michael@0: SkDEBUGCODE(bool extracted = )bitmap.extractSubset(&fBitmaps[i], rect); michael@0: SkASSERT(extracted); michael@0: SkBaseDevice* device = new SkBitmapDevice(fBitmaps[i]); michael@0: SkCanvas* canvas = new SkCanvas(device); michael@0: device->unref(); michael@0: if (initial != NULL) { michael@0: canvas->setMatrix(*initial); michael@0: } michael@0: canvas->translate(SkIntToScalar(-rect.left()), michael@0: SkIntToScalar(-rect.top())); michael@0: if (0 == i) { michael@0: fReader.setCanvas(canvas); michael@0: } else { michael@0: fReaders[i - 1].setCanvas(canvas); michael@0: fReaders[i - 1].setBitmapDecoder(proc); michael@0: } michael@0: canvas->unref(); michael@0: } michael@0: } michael@0: michael@0: void TiledPipeController::notifyWritten(size_t bytes) { michael@0: for (int i = 0; i < NumberOfTiles - 1; i++) { michael@0: fReaders[i].playback(this->getData(), bytes); michael@0: } michael@0: this->INHERITED::notifyWritten(bytes); michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: ThreadSafePipeController::ThreadSafePipeController(int numberOfReaders) michael@0: : fAllocator(kMinBlockSize) michael@0: , fNumberOfReaders(numberOfReaders) { michael@0: fBlock = NULL; michael@0: fBytesWritten = 0; michael@0: } michael@0: michael@0: void* ThreadSafePipeController::requestBlock(size_t minRequest, size_t *actual) { michael@0: if (fBlock) { michael@0: // Save the previous block for later michael@0: PipeBlock previousBloc(fBlock, fBytesWritten); michael@0: fBlockList.push(previousBloc); michael@0: } michael@0: int32_t blockSize = SkMax32(SkToS32(minRequest), kMinBlockSize); michael@0: fBlock = fAllocator.allocThrow(blockSize); michael@0: fBytesWritten = 0; michael@0: *actual = blockSize; michael@0: return fBlock; michael@0: } michael@0: michael@0: void ThreadSafePipeController::notifyWritten(size_t bytes) { michael@0: fBytesWritten += bytes; michael@0: } michael@0: michael@0: void ThreadSafePipeController::draw(SkCanvas* target) { michael@0: SkGPipeReader reader(target); michael@0: for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) { michael@0: reader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fBytes); michael@0: } michael@0: michael@0: if (fBlock) { michael@0: reader.playback(fBlock, fBytesWritten); michael@0: } michael@0: }