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
PipeController(SkCanvas * target)15 PipeController::PipeController(SkCanvas* target)
16 :fReader(target) {
17 fBlock = NULL;
18 fBlockSize = fBytesWritten = 0;
19 }
20
~PipeController()21 PipeController::~PipeController() {
22 sk_free(fBlock);
23 }
24
requestBlock(size_t minRequest,size_t * actual)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
notifyWritten(size_t bytes)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
TiledPipeController(const SkBitmap & bitmap,const SkMatrix * initial)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
notifyWritten(size_t bytes)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
ThreadSafePipeController(int numberOfReaders)82 ThreadSafePipeController::ThreadSafePipeController(int numberOfReaders)
83 : fAllocator(kMinBlockSize)
84 , fNumberOfReaders(numberOfReaders) {
85 fBlock = NULL;
86 fBytesWritten = 0;
87 }
88
requestBlock(size_t minRequest,size_t * actual)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
notifyWritten(size_t bytes)102 void ThreadSafePipeController::notifyWritten(size_t bytes) {
103 fBytesWritten += bytes;
104 }
105
draw(SkCanvas * target)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