blob: a23d77537c0e94a06f85b2251d217b2ca657389a [file] [log] [blame]
scroggo@google.com72c96722012-06-06 21:07:10 +00001/*
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"
scroggo@google.comb073d922012-06-08 15:35:03 +00009
scroggo@google.com72c96722012-06-06 21:07:10 +000010#include "SkCanvas.h"
11#include "SkDevice.h"
12#include "SkGPipe.h"
scroggo@google.comb073d922012-06-08 15:35:03 +000013#include "SkMatrix.h"
scroggo@google.com72c96722012-06-06 21:07:10 +000014
scroggo@google.com74b7ffd2013-04-30 02:32:41 +000015PipeController::PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc)
scroggo@google.com72c96722012-06-06 21:07:10 +000016:fReader(target) {
17 fBlock = NULL;
18 fBlockSize = fBytesWritten = 0;
scroggo@google.com74b7ffd2013-04-30 02:32:41 +000019 fReader.setBitmapDecoder(proc);
scroggo@google.com72c96722012-06-06 21:07:10 +000020}
21
22PipeController::~PipeController() {
23 sk_free(fBlock);
24}
25
26void* 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
35void 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
scroggo@google.comb073d922012-06-08 15:35:03 +000043TiledPipeController::TiledPipeController(const SkBitmap& bitmap,
scroggo@google.com74b7ffd2013-04-30 02:32:41 +000044 SkPicture::InstallPixelRefProc proc,
scroggo@google.comb073d922012-06-08 15:35:03 +000045 const SkMatrix* initial)
scroggo@google.com74b7ffd2013-04-30 02:32:41 +000046: INHERITED(NULL, proc) {
scroggo@google.com72c96722012-06-06 21:07:10 +000047 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
humper@google.com0e515772013-01-07 19:54:40 +000056 SkDEBUGCODE(bool extracted = )bitmap.extractSubset(&fBitmaps[i], rect);
scroggo@google.com72c96722012-06-06 21:07:10 +000057 SkASSERT(extracted);
robertphillips@google.com9b051a32013-08-20 20:06:40 +000058 SkDevice* device = new SkDevice(fBitmaps[i]);
scroggo@google.com72c96722012-06-06 21:07:10 +000059 SkCanvas* canvas = new SkCanvas(device);
60 device->unref();
scroggo@google.comb073d922012-06-08 15:35:03 +000061 if (initial != NULL) {
62 canvas->setMatrix(*initial);
63 }
scroggo@google.com72c96722012-06-06 21:07:10 +000064 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);
scroggo@google.com74b7ffd2013-04-30 02:32:41 +000070 fReaders[i - 1].setBitmapDecoder(proc);
scroggo@google.com72c96722012-06-06 21:07:10 +000071 }
72 canvas->unref();
73 }
74}
75
76void 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}
scroggo@google.com58b4ead2012-08-31 16:15:22 +000082
83////////////////////////////////////////////////////////////////////////////////
84
scroggo@google.com8e073ba2012-08-31 16:25:46 +000085ThreadSafePipeController::ThreadSafePipeController(int numberOfReaders)
scroggo@google.com58b4ead2012-08-31 16:15:22 +000086: fAllocator(kMinBlockSize)
87, fNumberOfReaders(numberOfReaders) {
88 fBlock = NULL;
89 fBytesWritten = 0;
90}
91
scroggo@google.com8e073ba2012-08-31 16:25:46 +000092void* ThreadSafePipeController::requestBlock(size_t minRequest, size_t *actual) {
scroggo@google.com58b4ead2012-08-31 16:15:22 +000093 if (fBlock) {
94 // Save the previous block for later
95 PipeBlock previousBloc(fBlock, fBytesWritten);
96 fBlockList.push(previousBloc);
97 }
scroggo@google.come5f48242013-02-25 21:47:41 +000098 int32_t blockSize = SkMax32(SkToS32(minRequest), kMinBlockSize);
scroggo@google.com58b4ead2012-08-31 16:15:22 +000099 fBlock = fAllocator.allocThrow(blockSize);
100 fBytesWritten = 0;
101 *actual = blockSize;
102 return fBlock;
103}
104
scroggo@google.com8e073ba2012-08-31 16:25:46 +0000105void ThreadSafePipeController::notifyWritten(size_t bytes) {
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000106 fBytesWritten += bytes;
107}
108
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000109void ThreadSafePipeController::draw(SkCanvas* target) {
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000110 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}