|
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 "SkBitmapDevice.h" |
|
11 #include "SkCanvas.h" |
|
12 #include "SkGPipe.h" |
|
13 #include "SkMatrix.h" |
|
14 |
|
15 PipeController::PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc) |
|
16 :fReader(target) { |
|
17 fBlock = NULL; |
|
18 fBlockSize = fBytesWritten = 0; |
|
19 fReader.setBitmapDecoder(proc); |
|
20 } |
|
21 |
|
22 PipeController::~PipeController() { |
|
23 sk_free(fBlock); |
|
24 } |
|
25 |
|
26 void* 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 |
|
35 void 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 |
|
43 TiledPipeController::TiledPipeController(const SkBitmap& bitmap, |
|
44 SkPicture::InstallPixelRefProc proc, |
|
45 const SkMatrix* initial) |
|
46 : INHERITED(NULL, proc) { |
|
47 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 |
|
56 SkDEBUGCODE(bool extracted = )bitmap.extractSubset(&fBitmaps[i], rect); |
|
57 SkASSERT(extracted); |
|
58 SkBaseDevice* device = new SkBitmapDevice(fBitmaps[i]); |
|
59 SkCanvas* canvas = new SkCanvas(device); |
|
60 device->unref(); |
|
61 if (initial != NULL) { |
|
62 canvas->setMatrix(*initial); |
|
63 } |
|
64 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); |
|
70 fReaders[i - 1].setBitmapDecoder(proc); |
|
71 } |
|
72 canvas->unref(); |
|
73 } |
|
74 } |
|
75 |
|
76 void 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 } |
|
82 |
|
83 //////////////////////////////////////////////////////////////////////////////// |
|
84 |
|
85 ThreadSafePipeController::ThreadSafePipeController(int numberOfReaders) |
|
86 : fAllocator(kMinBlockSize) |
|
87 , fNumberOfReaders(numberOfReaders) { |
|
88 fBlock = NULL; |
|
89 fBytesWritten = 0; |
|
90 } |
|
91 |
|
92 void* ThreadSafePipeController::requestBlock(size_t minRequest, size_t *actual) { |
|
93 if (fBlock) { |
|
94 // Save the previous block for later |
|
95 PipeBlock previousBloc(fBlock, fBytesWritten); |
|
96 fBlockList.push(previousBloc); |
|
97 } |
|
98 int32_t blockSize = SkMax32(SkToS32(minRequest), kMinBlockSize); |
|
99 fBlock = fAllocator.allocThrow(blockSize); |
|
100 fBytesWritten = 0; |
|
101 *actual = blockSize; |
|
102 return fBlock; |
|
103 } |
|
104 |
|
105 void ThreadSafePipeController::notifyWritten(size_t bytes) { |
|
106 fBytesWritten += bytes; |
|
107 } |
|
108 |
|
109 void ThreadSafePipeController::draw(SkCanvas* target) { |
|
110 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 } |