• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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