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

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, 9 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
« no previous file with comments | « src/effects/SkTileImageFilter.cpp ('k') | src/gpu/GrLayerHoister.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 25 matching lines...) Expand all
36 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode()); 36 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
37 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect ()); 37 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect ());
38 } 38 }
39 39
40 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { 40 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
41 this->INHERITED::flatten(buffer); 41 this->INHERITED::flatten(buffer);
42 buffer.writeFlattenable(fMode); 42 buffer.writeFlattenable(fMode);
43 } 43 }
44 44
45 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, 45 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
46 const SkBitmap& src, 46 const SkImage* src,
47 const Context& ctx, 47 const Context& ctx,
48 SkBitmap* dst, 48 SkAutoTUnref<const SkImage>& dst,
49 SkIPoint* offset) const { 49 SkIPoint* offset) const {
50 SkBitmap background = src, foreground = src; 50 SkAutoTUnref<const SkImage> background(SkRef(src));
51 SkAutoTUnref<const SkImage> foreground(SkRef(src));
51 SkImageFilter* backgroundInput = getInput(0); 52 SkImageFilter* backgroundInput = getInput(0);
52 SkImageFilter* foregroundInput = getInput(1); 53 SkImageFilter* foregroundInput = getInput(1);
53 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 54 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
54 if (backgroundInput && 55 if (backgroundInput &&
55 !backgroundInput->filterImage(proxy, src, ctx, &background, &backgroundO ffset)) { 56 !backgroundInput->filterImage(proxy, src, ctx, background, &backgroundOf fset)) {
56 background.reset(); 57 background.reset(NULL);
57 } 58 }
58 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 59 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
59 if (foregroundInput && 60 if (foregroundInput &&
60 !foregroundInput->filterImage(proxy, src, ctx, &foreground, &foregroundO ffset)) { 61 !foregroundInput->filterImage(proxy, src, ctx, foreground, &foregroundOf fset)) {
61 foreground.reset(); 62 foreground.reset(NULL);
62 } 63 }
63 64
64 SkIRect bounds, foregroundBounds; 65 SkIRect bounds, foregroundBounds;
65 if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) { 66 if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) {
66 foregroundBounds.setEmpty(); 67 foregroundBounds.setEmpty();
67 foreground.reset(); 68 foreground.reset(NULL);
68 } 69 }
69 if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) { 70 if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) {
70 bounds.setEmpty(); 71 bounds.setEmpty();
71 background.reset(); 72 background.reset(NULL);
72 } 73 }
73 bounds.join(foregroundBounds); 74 bounds.join(foregroundBounds);
74 if (bounds.isEmpty()) { 75 if (bounds.isEmpty()) {
75 return false; 76 return false;
76 } 77 }
77 78
78 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height())); 79 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height()));
79 if (NULL == device.get()) { 80 if (NULL == device.get()) {
80 return false; 81 return false;
81 } 82 }
82 SkCanvas canvas(device); 83 SkCanvas canvas(device);
83 canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()) ); 84 canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()) );
84 SkPaint paint; 85 SkPaint paint;
85 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 86 if (NULL != background) {
86 canvas.drawBitmap(background, SkIntToScalar(backgroundOffset.fX), 87 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
87 SkIntToScalar(backgroundOffset.fY), &paint); 88 canvas.drawImage(background, SkIntToScalar(backgroundOffset.fX),
89 SkIntToScalar(backgroundOffset.fY), &paint);
90 }
88 paint.setXfermode(fMode); 91 paint.setXfermode(fMode);
89 canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX), 92 if (NULL != foreground) {
90 SkIntToScalar(foregroundOffset.fY), &paint); 93 canvas.drawImage(foreground, SkIntToScalar(foregroundOffset.fX),
94 SkIntToScalar(foregroundOffset.fY), &paint);
95 }
91 canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op); 96 canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op);
92 paint.setColor(SK_ColorTRANSPARENT); 97 paint.setColor(SK_ColorTRANSPARENT);
93 canvas.drawPaint(paint); 98 canvas.drawPaint(paint);
94 *dst = device->accessBitmap(false); 99
100 foreground.reset(NULL);
101 background.reset(NULL);
102
103 SkImage* image = device->newImageSnapshot();
104 if (NULL == image) {
105 return false;
106 }
107 dst.reset(image);
108
95 offset->fX = bounds.left(); 109 offset->fX = bounds.left();
96 offset->fY = bounds.top(); 110 offset->fY = bounds.top();
97 return true; 111 return true;
98 } 112 }
99 113
100 #ifndef SK_IGNORE_TO_STRING 114 #ifndef SK_IGNORE_TO_STRING
101 void SkXfermodeImageFilter::toString(SkString* str) const { 115 void SkXfermodeImageFilter::toString(SkString* str) const {
102 str->appendf("SkXfermodeImageFilter: ("); 116 str->appendf("SkXfermodeImageFilter: (");
103 str->appendf("xfermode: ("); 117 str->appendf("xfermode: (");
104 if (fMode) { 118 if (fMode) {
105 fMode->toString(str); 119 fMode->toString(str);
106 } 120 }
107 str->append("))"); 121 str->append("))");
108 } 122 }
109 #endif 123 #endif
110 124
111 #if SK_SUPPORT_GPU 125 #if SK_SUPPORT_GPU
112 126
113 bool SkXfermodeImageFilter::canFilterImageGPU() const { 127 bool SkXfermodeImageFilter::canFilterImageGPU() const {
114 return fMode && fMode->asFragmentProcessor(NULL, NULL) && !cropRectIsSet(); 128 return fMode && fMode->asFragmentProcessor(NULL, NULL) && !cropRectIsSet();
115 } 129 }
116 130
117 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, 131 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
118 const SkBitmap& src, 132 const SkImage* src,
119 const Context& ctx, 133 const Context& ctx,
120 SkBitmap* result, 134 SkAutoTUnref<const SkImage>& result,
121 SkIPoint* offset) const { 135 SkIPoint* offset) const {
122 SkBitmap background = src; 136 SkAutoTUnref<const SkImage> background(SkRef(src));
123 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 137 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
124 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &backgro und, 138 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, backgrou nd,
125 &backgroundOffset)) { 139 &backgroundOffset)) {
126 return onFilterImage(proxy, src, ctx, result, offset); 140 return onFilterImage(proxy, src, ctx, result, offset);
127 } 141 }
128 GrTexture* backgroundTex = background.getTexture(); 142 GrTexture* backgroundTex = background->getTexture();
129 143
130 if (NULL == backgroundTex) { 144 if (NULL == backgroundTex) {
131 SkASSERT(false); 145 SkASSERT(false);
132 return false; 146 return false;
133 } 147 }
134 148
135 SkBitmap foreground = src; 149 SkAutoTUnref<const SkImage> foreground(SkRef(src));
136 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 150 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
137 if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, &foregro und, 151 if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, foregrou nd,
138 &foregroundOffset)) { 152 &foregroundOffset)) {
139 return onFilterImage(proxy, src, ctx, result, offset); 153 return onFilterImage(proxy, src, ctx, result, offset);
140 } 154 }
141 GrTexture* foregroundTex = foreground.getTexture(); 155 GrTexture* foregroundTex = foreground->getTexture();
142 GrContext* context = foregroundTex->getContext(); 156 GrContext* context = foregroundTex->getContext();
143 157
144 GrFragmentProcessor* xferProcessor = NULL; 158 GrFragmentProcessor* xferProcessor = NULL;
145 159
160 const SkRect srcRect = SkRect::MakeWH(src->width(), src->height());
161
146 GrSurfaceDesc desc; 162 GrSurfaceDesc desc;
147 desc.fFlags = kRenderTarget_GrSurfaceFlag; 163 desc.fFlags = kRenderTarget_GrSurfaceFlag;
148 desc.fWidth = src.width(); 164 desc.fWidth = srcRect.width();
149 desc.fHeight = src.height(); 165 desc.fHeight = srcRect.height();
150 desc.fConfig = kSkia8888_GrPixelConfig; 166 desc.fConfig = kSkia8888_GrPixelConfig;
151 SkAutoTUnref<GrTexture> dst( 167 SkAutoTUnref<GrTexture> dst(
152 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); 168 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
153 if (!dst) { 169 if (!dst) {
154 return false; 170 return false;
155 } 171 }
156 172
157 if (!fMode || !fMode->asFragmentProcessor(&xferProcessor, backgroundTex)) { 173 if (!fMode || !fMode->asFragmentProcessor(&xferProcessor, backgroundTex)) {
158 // canFilterImageGPU() should've taken care of this 174 // canFilterImageGPU() should've taken care of this
159 SkASSERT(false); 175 SkASSERT(false);
160 return false; 176 return false;
161 } 177 }
162 178
163 SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foreg roundTex); 179 SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foreg roundTex);
164 foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOf fset.fX), 180 foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOf fset.fX),
165 SkIntToScalar(backgroundOffset.fY-foregroundOf fset.fY)); 181 SkIntToScalar(backgroundOffset.fY-foregroundOf fset.fY));
166 182
167 183
168 SkRect srcRect; 184
169 src.getBounds(&srcRect);
170 185
171 GrPaint paint; 186 GrPaint paint;
172 paint.addColorTextureProcessor(foregroundTex, foregroundMatrix); 187 paint.addColorTextureProcessor(foregroundTex, foregroundMatrix);
173 paint.addColorProcessor(xferProcessor)->unref(); 188 paint.addColorProcessor(xferProcessor)->unref();
174 context->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix ::I(), srcRect); 189 context->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix ::I(), srcRect);
175 190
176 offset->fX = backgroundOffset.fX; 191 offset->fX = backgroundOffset.fX;
177 offset->fY = backgroundOffset.fY; 192 offset->fY = backgroundOffset.fY;
178 WrapTexture(dst, src.width(), src.height(), result); 193 if (!WrapTexture(dst, srcRect.width(), srcRect.height(), result)) {
194 return false;
195 }
179 return true; 196 return true;
180 } 197 }
181 198
182 #endif 199 #endif
183 200
OLDNEW
« no previous file with comments | « src/effects/SkTileImageFilter.cpp ('k') | src/gpu/GrLayerHoister.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698