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