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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/Image.cpp

Issue 1331533002: [poc] curve-filter Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Ensure screen device profiles are matrix Created 4 years, 12 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 (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 18 matching lines...) Expand all
29 #include "platform/Length.h" 29 #include "platform/Length.h"
30 #include "platform/MIMETypeRegistry.h" 30 #include "platform/MIMETypeRegistry.h"
31 #include "platform/PlatformInstrumentation.h" 31 #include "platform/PlatformInstrumentation.h"
32 #include "platform/RuntimeEnabledFeatures.h" 32 #include "platform/RuntimeEnabledFeatures.h"
33 #include "platform/SharedBuffer.h" 33 #include "platform/SharedBuffer.h"
34 #include "platform/TraceEvent.h" 34 #include "platform/TraceEvent.h"
35 #include "platform/geometry/FloatPoint.h" 35 #include "platform/geometry/FloatPoint.h"
36 #include "platform/geometry/FloatRect.h" 36 #include "platform/geometry/FloatRect.h"
37 #include "platform/geometry/FloatSize.h" 37 #include "platform/geometry/FloatSize.h"
38 #include "platform/graphics/BitmapImage.h" 38 #include "platform/graphics/BitmapImage.h"
39 #include "platform/graphics/ColorSpaceFilter.h"
40 #include "platform/graphics/ColorSpaceProfile.h"
39 #include "platform/graphics/DeferredImageDecoder.h" 41 #include "platform/graphics/DeferredImageDecoder.h"
40 #include "platform/graphics/GraphicsContext.h" 42 #include "platform/graphics/GraphicsContext.h"
43 #include "platform/graphics/GraphicsScreen.h"
41 #include "public/platform/Platform.h" 44 #include "public/platform/Platform.h"
42 #include "public/platform/WebData.h" 45 #include "public/platform/WebData.h"
43 #include "third_party/skia/include/core/SkCanvas.h" 46 #include "third_party/skia/include/core/SkCanvas.h"
44 #include "third_party/skia/include/core/SkImage.h" 47 #include "third_party/skia/include/core/SkImage.h"
45 #include "third_party/skia/include/core/SkPictureRecorder.h" 48 #include "third_party/skia/include/core/SkPictureRecorder.h"
46 #include "wtf/MainThread.h" 49 #include "wtf/MainThread.h"
47 #include "wtf/StdLibExtras.h" 50 #include "wtf/StdLibExtras.h"
48 51
49 #include <math.h> 52 #include <math.h>
50 53
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 ctxt.setImageInterpolationQuality(InterpolationLow); 179 ctxt.setImageInterpolationQuality(InterpolationLow);
177 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); 180 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect);
178 ctxt.setImageInterpolationQuality(previousInterpolationQuality); 181 ctxt.setImageInterpolationQuality(previousInterpolationQuality);
179 } else { 182 } else {
180 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); 183 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect);
181 } 184 }
182 185
183 startAnimation(); 186 startAnimation();
184 } 187 }
185 188
186 namespace { 189 static PassRefPtr<SkShader> createPatternShader(const SkImage* image, SkPaint* p aint, const SkMatrix& shaderMatrix, const FloatSize& spacing)
187
188 PassRefPtr<SkShader> createPatternShader(const SkImage* image, const SkMatrix& s haderMatrix,
189 const SkPaint& paint, const FloatSize& spacing)
190 { 190 {
191 if (spacing.isZero()) 191 if (spacing.isZero())
192 return adoptRef(image->newShader(SkShader::kRepeat_TileMode, SkShader::k Repeat_TileMode, &shaderMatrix)); 192 return adoptRef(image->newShader(SkShader::kRepeat_TileMode, SkShader::k Repeat_TileMode, &shaderMatrix));
193 193
194 // Arbitrary tiling is currently only supported for SkPictureShader - so we use it instead 194 // Arbitrary tiling is currently only supported for SkPictureShader so use i t, instead
195 // of a plain bitmap shader to implement spacing. 195 // of a plain bitmap shader, to implement spacing (CSS background-repeat: sp ace).
196 const SkRect tileRect = SkRect::MakeWH( 196 SkRect tileRect = SkRect::MakeWH(image->width() + spacing.width(), image->he ight() + spacing.height());
197 image->width() + spacing.width(),
198 image->height() + spacing.height());
199 197
200 SkPictureRecorder recorder; 198 SkPictureRecorder recorder;
201 SkCanvas* canvas = recorder.beginRecording(tileRect); 199 SkCanvas* canvas = recorder.beginRecording(tileRect);
202 canvas->drawImage(image, 0, 0, &paint); 200 canvas->drawImage(image, 0, 0, paint);
203 RefPtr<const SkPicture> picture = adoptRef(recorder.endRecordingAsPicture()) ; 201 RefPtr<const SkPicture> picture = adoptRef(recorder.endRecordingAsPicture()) ;
204 202
205 return adoptRef(SkShader::CreatePictureShader( 203 // Remove any color filter from callers paint: it is applied when drawing th e SkPicture
206 picture.get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, & shaderMatrix, nullptr)); 204 // shader so clearing it here prevents caller from applying the filter twice .
205 if (paint->getColorFilter())
206 paint->setColorFilter(nullptr);
207
208 return adoptRef(SkShader::CreatePictureShader(picture.get(), SkShader::kRepe at_TileMode, SkShader::kRepeat_TileMode, &shaderMatrix, nullptr));
207 } 209 }
208 210
209 } // anonymous namespace 211 inline PassRefPtr<ColorSpaceProfile> sourceColorProfile(Image* image)
212 {
213 return image->isBitmapImage() ? toBitmapImage(image)->colorProfile() : nullp tr;
214 }
210 215
211 void Image::drawPattern(GraphicsContext& context, const FloatRect& floatSrcRect, const FloatSize& scale, 216 void Image::drawPattern(GraphicsContext& context, const FloatRect& floatSrcRect, const FloatSize& scale,
212 const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& dest Rect, const FloatSize& repeatSpacing) 217 const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& dest Rect, const FloatSize& repeatSpacing)
213 { 218 {
214 TRACE_EVENT0("skia", "Image::drawPattern"); 219 TRACE_EVENT0("skia", "Image::drawPattern");
215 220
216 RefPtr<SkImage> image = imageForCurrentFrame(); 221 RefPtr<SkImage> image = imageForCurrentFrame();
217 if (!image) 222 if (!image)
218 return; 223 return;
219 224
220 FloatRect normSrcRect = floatSrcRect; 225 FloatRect normSrcRect = floatSrcRect;
221 226
222 normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); 227 normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height()));
223 if (destRect.isEmpty() || normSrcRect.isEmpty()) 228 if (destRect.isEmpty() || normSrcRect.isEmpty())
224 return; // nothing to draw 229 return; // nothing to draw
225 230
226 SkMatrix localMatrix; 231 SkMatrix localMatrix;
227 // We also need to translate it such that the origin of the pattern is the 232 // We also need to translate it such that the origin of the pattern is the
228 // origin of the destination rect, which is what WebKit expects. Skia uses 233 // origin of the destination rect, which is what WebKit expects. Skia uses
229 // the coordinate system origin as the base for the pattern. If WebKit wants 234 // the coordinate system origin as the base for the pattern. If WebKit wants
230 // a shifted image, it will shift it from there using the localMatrix. 235 // a shifted image, it will shift it from there using the localMatrix.
231 const float adjustedX = phase.x() + normSrcRect.x() * scale.width(); 236 const float adjustedX = phase.x() + normSrcRect.x() * scale.width();
232 const float adjustedY = phase.y() + normSrcRect.y() * scale.height(); 237 const float adjustedY = phase.y() + normSrcRect.y() * scale.height();
233 localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjuste dY)); 238 localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjuste dY));
234 239
235 // Because no resizing occurred, the shader transform should be 240 // Because no resizing occurred, the shader transform should be
236 // set to the pattern's transform, which just includes scale. 241 // set to the pattern's transform, which just includes scale.
237 localMatrix.preScale(scale.width(), scale.height()); 242 localMatrix.preScale(scale.width(), scale.height());
238 243
239 // Fetch this now as subsetting may swap the image. 244 // Fetch the image ID now since subsetting may swap the image.
240 auto imageID = image->uniqueID(); 245 auto imageID = image->uniqueID();
241
242 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect))); 246 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect)));
243 if (!image) 247 if (!image)
244 return; 248 return;
245 249
246 { 250 RefPtr<SkColorFilter> colorTransform;
247 SkPaint paint = context.fillPaint(); 251 if (RefPtr<ColorSpaceProfile> source = sourceColorProfile(this)) {
248 paint.setColor(SK_ColorBLACK); 252 // Tagged images (those that have a color profile) are drawn color-corre ct on supported platforms.
249 paint.setXfermodeMode(compositeOp); 253 RefPtr<ColorSpaceProfile> target = screenColorProfile(currentScreenId()) ;
250 paint.setFilterQuality(context.computeFilterQuality(this, destRect, norm SrcRect)); 254 if (!context.colorFilter()) // http://crbug.com/542498
251 paint.setAntiAlias(context.shouldAntialias()); 255 colorTransform = createColorSpaceFilter(source.get(), target.get());
252 RefPtr<SkShader> shader = createPatternShader(image.get(), localMatrix, paint, 256 RELEASE_ASSERT(currentScreenId());
253 FloatSize(repeatSpacing.width() / scale.width(), repeatSpacing.heigh t() / scale.height()));
254 paint.setShader(shader.get());
255 context.drawRect(destRect, paint);
256 } 257 }
257 258
259 SkPaint paint = context.fillPaint();
260 paint.setColor(SK_ColorBLACK);
261 paint.setXfermodeMode(compositeOp);
262 paint.setFilterQuality(context.computeFilterQuality(this, destRect, normSrcR ect));
263 paint.setAntiAlias(context.shouldAntialias());
264
265 // BoxPainter background paint can set a luminance color filter on the conte xt. Add it to the paint if
266 // present: see layout test css3/masking/mask-luminance-png.html and http:// crbug.com/542498
267 if (context.colorFilter()) {
268 fprintf(stderr, "Image::drawPattern color filter\n");
269 paint.setColorFilter(context.colorFilter());
270 fflush(stderr);
271 } else if (colorTransform.get()) {
272 fprintf(stderr, "Image::drawPattern color transform key [%s]\n", colorSp aceFilterKey(colorTransform.get()).latin1().data());
273 paint.setColorFilter(colorTransform.get());
274 fflush(stderr);
275 }
276
277 FloatSize spacing = FloatSize(repeatSpacing.width() / scale.width(), repeatS pacing.height() / scale.height());
278 RefPtr<SkShader> shader = createPatternShader(image.get(), &paint, localMatr ix, spacing);
279 paint.setShader(shader.get());
280
281 context.drawRect(destRect, paint);
282
258 if (currentFrameIsLazyDecoded()) 283 if (currentFrameIsLazyDecoded())
259 PlatformInstrumentation::didDrawLazyPixelRef(imageID); 284 PlatformInstrumentation::didDrawLazyPixelRef(imageID);
260 } 285 }
261 286
262 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic Height, FloatSize& intrinsicRatio) 287 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic Height, FloatSize& intrinsicRatio)
263 { 288 {
264 intrinsicRatio = FloatSize(size()); 289 intrinsicRatio = FloatSize(size());
265 intrinsicWidth = Length(intrinsicRatio.width(), Fixed); 290 intrinsicWidth = Length(intrinsicRatio.width(), Fixed);
266 intrinsicHeight = Length(intrinsicRatio.height(), Fixed); 291 intrinsicHeight = Length(intrinsicRatio.height(), Fixed);
267 } 292 }
268 293
269 PassRefPtr<Image> Image::imageForDefaultFrame() 294 PassRefPtr<Image> Image::imageForDefaultFrame()
270 { 295 {
271 RefPtr<Image> image(this); 296 RefPtr<Image> image(this);
272 297
273 return image.release(); 298 return image.release();
274 } 299 }
275 300
276 bool Image::isTextureBacked() 301 bool Image::isTextureBacked()
277 { 302 {
278 RefPtr<SkImage> image = imageForCurrentFrame(); 303 RefPtr<SkImage> image = imageForCurrentFrame();
279 return image ? image->isTextureBacked() : false; 304 return image ? image->isTextureBacked() : false;
280 } 305 }
281 306
282 } // namespace blink 307 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698