/*
 * 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 "SkCanvas.h"
#include "SkDevice.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);
        SkDevice* device = new SkDevice(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);
    }
}
