1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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;
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);
}
}
|