Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: src/effects/SkXfermodeImageFilter.cpp

Issue 920513003: Make filters use SkImage instead of SkBitmap Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2013 The Android Open Source Project 2 * Copyright 2013 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkXfermodeImageFilter.h" 8 #include "SkXfermodeImageFilter.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkDevice.h" 10 #include "SkDevice.h"
(...skipping 26 matching lines...) Expand all
37 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode()); 37 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
38 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect (), common.uniqueID()); 38 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect (), common.uniqueID());
39 } 39 }
40 40
41 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { 41 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
42 this->INHERITED::flatten(buffer); 42 this->INHERITED::flatten(buffer);
43 buffer.writeFlattenable(fMode); 43 buffer.writeFlattenable(fMode);
44 } 44 }
45 45
46 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, 46 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
47 const SkBitmap& src, 47 const SkImage* src,
48 const Context& ctx, 48 const Context& ctx,
49 SkBitmap* dst, 49 SkAutoTUnref<const SkImage>& dst,
50 SkIPoint* offset) const { 50 SkIPoint* offset) const {
51 SkBitmap background = src, foreground = src; 51 SkAutoTUnref<const SkImage> background(SkRef(src));
52 SkAutoTUnref<const SkImage> foreground(SkRef(src));
52 SkImageFilter* backgroundInput = getInput(0); 53 SkImageFilter* backgroundInput = getInput(0);
53 SkImageFilter* foregroundInput = getInput(1); 54 SkImageFilter* foregroundInput = getInput(1);
54 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 55 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
55 if (backgroundInput && 56 if (backgroundInput &&
56 !backgroundInput->filterImage(proxy, src, ctx, &background, &backgroundO ffset)) { 57 !backgroundInput->filterImage(proxy, src, ctx, background, &backgroundOf fset)) {
57 background.reset(); 58 background.reset(NULL);
58 } 59 }
59 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 60 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
60 if (foregroundInput && 61 if (foregroundInput &&
61 !foregroundInput->filterImage(proxy, src, ctx, &foreground, &foregroundO ffset)) { 62 !foregroundInput->filterImage(proxy, src, ctx, foreground, &foregroundOf fset)) {
62 foreground.reset(); 63 foreground.reset(NULL);
63 } 64 }
64 65
65 SkIRect bounds, foregroundBounds; 66 SkIRect bounds, foregroundBounds;
66 if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) { 67 if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) {
67 foregroundBounds.setEmpty(); 68 foregroundBounds.setEmpty();
68 foreground.reset(); 69 foreground.reset(NULL);
69 } 70 }
70 if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) { 71 if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) {
71 bounds.setEmpty(); 72 bounds.setEmpty();
72 background.reset(); 73 background.reset(NULL);
73 } 74 }
74 bounds.join(foregroundBounds); 75 bounds.join(foregroundBounds);
75 if (bounds.isEmpty()) { 76 if (bounds.isEmpty()) {
76 return false; 77 return false;
77 } 78 }
78 79
79 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height())); 80 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height()));
80 if (NULL == device.get()) { 81 if (NULL == device.get()) {
81 return false; 82 return false;
82 } 83 }
83 SkCanvas canvas(device); 84 SkCanvas canvas(device);
84 canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()) ); 85 canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()) );
85 SkPaint paint; 86 SkPaint paint;
86 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 87 if (NULL != background) {
87 canvas.drawBitmap(background, SkIntToScalar(backgroundOffset.fX), 88 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
88 SkIntToScalar(backgroundOffset.fY), &paint); 89 canvas.drawImage(background, SkIntToScalar(backgroundOffset.fX),
90 SkIntToScalar(backgroundOffset.fY), &paint);
91 }
89 paint.setXfermode(fMode); 92 paint.setXfermode(fMode);
90 canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX), 93 if (NULL != foreground) {
91 SkIntToScalar(foregroundOffset.fY), &paint); 94 canvas.drawImage(foreground, SkIntToScalar(foregroundOffset.fX),
95 SkIntToScalar(foregroundOffset.fY), &paint);
96 }
92 canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op); 97 canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op);
93 paint.setColor(SK_ColorTRANSPARENT); 98 paint.setColor(SK_ColorTRANSPARENT);
94 canvas.drawPaint(paint); 99 canvas.drawPaint(paint);
95 *dst = device->accessBitmap(false); 100
101 foreground.reset(NULL);
102 background.reset(NULL);
103
104 SkImage* image = device->newImageSnapshot();
105 if (NULL == image) {
106 return false;
107 }
108 dst.reset(image);
109
96 offset->fX = bounds.left(); 110 offset->fX = bounds.left();
97 offset->fY = bounds.top(); 111 offset->fY = bounds.top();
98 return true; 112 return true;
99 } 113 }
100 114
101 #ifndef SK_IGNORE_TO_STRING 115 #ifndef SK_IGNORE_TO_STRING
102 void SkXfermodeImageFilter::toString(SkString* str) const { 116 void SkXfermodeImageFilter::toString(SkString* str) const {
103 str->appendf("SkXfermodeImageFilter: ("); 117 str->appendf("SkXfermodeImageFilter: (");
104 str->appendf("xfermode: ("); 118 str->appendf("xfermode: (");
105 if (fMode) { 119 if (fMode) {
106 fMode->toString(str); 120 fMode->toString(str);
107 } 121 }
108 str->append("))"); 122 str->append("))");
109 } 123 }
110 #endif 124 #endif
111 125
112 #if SK_SUPPORT_GPU 126 #if SK_SUPPORT_GPU
113 127
114 bool SkXfermodeImageFilter::canFilterImageGPU() const { 128 bool SkXfermodeImageFilter::canFilterImageGPU() const {
115 return fMode && fMode->asFragmentProcessor(NULL, NULL) && !cropRectIsSet(); 129 return fMode && fMode->asFragmentProcessor(NULL, NULL) && !cropRectIsSet();
116 } 130 }
117 131
118 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, 132 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
119 const SkBitmap& src, 133 const SkImage* src,
120 const Context& ctx, 134 const Context& ctx,
121 SkBitmap* result, 135 SkAutoTUnref<const SkImage>& result,
122 SkIPoint* offset) const { 136 SkIPoint* offset) const {
123 SkBitmap background = src; 137 SkAutoTUnref<const SkImage> background(SkRef(src));
124 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 138 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
125 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &backgro und, 139 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, backgrou nd,
126 &backgroundOffset)) { 140 &backgroundOffset)) {
127 return onFilterImage(proxy, src, ctx, result, offset); 141 return onFilterImage(proxy, src, ctx, result, offset);
128 } 142 }
129 GrTexture* backgroundTex = background.getTexture(); 143 GrTexture* backgroundTex = background->getTexture();
130 144
131 if (NULL == backgroundTex) { 145 if (NULL == backgroundTex) {
132 SkASSERT(false); 146 SkASSERT(false);
133 return false; 147 return false;
134 } 148 }
135 149
136 SkBitmap foreground = src; 150 SkAutoTUnref<const SkImage> foreground(SkRef(src));
137 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 151 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
138 if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, &foregro und, 152 if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, foregrou nd,
139 &foregroundOffset)) { 153 &foregroundOffset)) {
140 return onFilterImage(proxy, src, ctx, result, offset); 154 return onFilterImage(proxy, src, ctx, result, offset);
141 } 155 }
142 GrTexture* foregroundTex = foreground.getTexture(); 156 GrTexture* foregroundTex = foreground->getTexture();
143 GrContext* context = foregroundTex->getContext(); 157 GrContext* context = foregroundTex->getContext();
144 158
145 GrFragmentProcessor* xferProcessor = NULL; 159 GrFragmentProcessor* xferProcessor = NULL;
146 160
161 const SkRect srcRect = SkRect::MakeWH(src->width(), src->height());
162
147 GrSurfaceDesc desc; 163 GrSurfaceDesc desc;
148 desc.fFlags = kRenderTarget_GrSurfaceFlag; 164 desc.fFlags = kRenderTarget_GrSurfaceFlag;
149 desc.fWidth = src.width(); 165 desc.fWidth = srcRect.width();
150 desc.fHeight = src.height(); 166 desc.fHeight = srcRect.height();
151 desc.fConfig = kSkia8888_GrPixelConfig; 167 desc.fConfig = kSkia8888_GrPixelConfig;
152 SkAutoTUnref<GrTexture> dst( 168 SkAutoTUnref<GrTexture> dst(
153 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); 169 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
154 if (!dst) { 170 if (!dst) {
155 return false; 171 return false;
156 } 172 }
157 173
158 if (!fMode || !fMode->asFragmentProcessor(&xferProcessor, backgroundTex)) { 174 if (!fMode || !fMode->asFragmentProcessor(&xferProcessor, backgroundTex)) {
159 // canFilterImageGPU() should've taken care of this 175 // canFilterImageGPU() should've taken care of this
160 SkASSERT(false); 176 SkASSERT(false);
161 return false; 177 return false;
162 } 178 }
163 179
164 SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foreg roundTex); 180 SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foreg roundTex);
165 foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOf fset.fX), 181 foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOf fset.fX),
166 SkIntToScalar(backgroundOffset.fY-foregroundOf fset.fY)); 182 SkIntToScalar(backgroundOffset.fY-foregroundOf fset.fY));
167 183
168 184
169 SkRect srcRect; 185
170 src.getBounds(&srcRect);
171 186
172 GrPaint paint; 187 GrPaint paint;
173 paint.addColorTextureProcessor(foregroundTex, foregroundMatrix); 188 paint.addColorTextureProcessor(foregroundTex, foregroundMatrix);
174 paint.addColorProcessor(xferProcessor)->unref(); 189 paint.addColorProcessor(xferProcessor)->unref();
175 context->drawRect(dst->asRenderTarget(), paint, SkMatrix::I(), srcRect); 190 context->drawRect(dst->asRenderTarget(), paint, SkMatrix::I(), srcRect);
176 191
177 offset->fX = backgroundOffset.fX; 192 offset->fX = backgroundOffset.fX;
178 offset->fY = backgroundOffset.fY; 193 offset->fY = backgroundOffset.fY;
179 WrapTexture(dst, src.width(), src.height(), result); 194 if (!WrapTexture(dst, srcRect.width(), srcRect.height(), result)) {
195 return false;
196 }
180 return true; 197 return true;
181 } 198 }
182 199
183 #endif 200 #endif
184 201
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698