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

Side by Side Diff: src/pdf/SkPDFDevice.cpp

Issue 1829693002: SkPDF: draw{Image,Bitmap} always serializes early (Closed) Base URL: https://skia.googlesource.com/skia.git@r1823683005
Patch Set: Don't put a sk_sp in a hashmap Created 4 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
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
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 "SkPDFDevice.h" 8 #include "SkPDFDevice.h"
9 9
10 #include "SkAnnotationKeys.h" 10 #include "SkAnnotationKeys.h"
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 if (bitmap.isOpaque()) { 1053 if (bitmap.isOpaque()) {
1054 replace_srcmode_on_opaque_paint(&paint); 1054 replace_srcmode_on_opaque_paint(&paint);
1055 } 1055 }
1056 1056
1057 if (d.fClip->isEmpty()) { 1057 if (d.fClip->isEmpty()) {
1058 return; 1058 return;
1059 } 1059 }
1060 1060
1061 SkMatrix transform = matrix; 1061 SkMatrix transform = matrix;
1062 transform.postConcat(*d.fMatrix); 1062 transform.postConcat(*d.fMatrix);
1063 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); 1063 SkImageBitmap imageBitmap(bitmap);
1064 if (!image) { 1064 this->internalDrawImage(
1065 return; 1065 transform, d.fClipStack, *d.fClip, imageBitmap, paint);
1066 }
1067 this->internalDrawImage(transform, d.fClipStack, *d.fClip, image, nullptr,
1068 paint);
1069 } 1066 }
1070 1067
1071 void SkPDFDevice::drawSprite(const SkDraw& d, 1068 void SkPDFDevice::drawSprite(const SkDraw& d,
1072 const SkBitmap& bitmap, 1069 const SkBitmap& bitmap,
1073 int x, 1070 int x,
1074 int y, 1071 int y,
1075 const SkPaint& srcPaint) { 1072 const SkPaint& srcPaint) {
1076 SkPaint paint = srcPaint; 1073 SkPaint paint = srcPaint;
1077 if (bitmap.isOpaque()) { 1074 if (bitmap.isOpaque()) {
1078 replace_srcmode_on_opaque_paint(&paint); 1075 replace_srcmode_on_opaque_paint(&paint);
1079 } 1076 }
1080 1077
1081 if (d.fClip->isEmpty()) { 1078 if (d.fClip->isEmpty()) {
1082 return; 1079 return;
1083 } 1080 }
1084 1081
1085 SkMatrix matrix; 1082 SkMatrix matrix;
1086 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 1083 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
1087 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); 1084 SkImageBitmap imageBitmap(bitmap);
1088 if (!image) { 1085 this->internalDrawImage(
1089 return; 1086 matrix, d.fClipStack, *d.fClip, imageBitmap, paint);
1090 }
1091 this->internalDrawImage(matrix, d.fClipStack, *d.fClip, image, nullptr,
1092 paint);
1093 } 1087 }
1094 1088
1095 void SkPDFDevice::drawImage(const SkDraw& draw, 1089 void SkPDFDevice::drawImage(const SkDraw& draw,
1096 const SkImage* image, 1090 const SkImage* image,
1097 SkScalar x, 1091 SkScalar x,
1098 SkScalar y, 1092 SkScalar y,
1099 const SkPaint& srcPaint) { 1093 const SkPaint& srcPaint) {
1100 SkPaint paint = srcPaint; 1094 SkPaint paint = srcPaint;
1101 if (!image) { 1095 if (!image) {
1102 return; 1096 return;
1103 } 1097 }
1104 if (image->isOpaque()) { 1098 if (image->isOpaque()) {
1105 replace_srcmode_on_opaque_paint(&paint); 1099 replace_srcmode_on_opaque_paint(&paint);
1106 } 1100 }
1107 if (draw.fClip->isEmpty()) { 1101 if (draw.fClip->isEmpty()) {
1108 return; 1102 return;
1109 } 1103 }
1110 SkMatrix transform = SkMatrix::MakeTrans(x, y); 1104 SkMatrix transform = SkMatrix::MakeTrans(x, y);
1111 transform.postConcat(*draw.fMatrix); 1105 transform.postConcat(*draw.fMatrix);
1112 this->internalDrawImage(transform, draw.fClipStack, *draw.fClip, image, 1106 SkImageBitmap imageBitmap(const_cast<SkImage*>(image));
1113 nullptr, paint); 1107 this->internalDrawImage(
1108 transform, draw.fClipStack, *draw.fClip, imageBitmap, paint);
1114 } 1109 }
1115 1110
1116 void SkPDFDevice::drawImageRect(const SkDraw& draw, 1111 void SkPDFDevice::drawImageRect(const SkDraw& draw,
1117 const SkImage* image, 1112 const SkImage* image,
1118 const SkRect* src, 1113 const SkRect* src,
1119 const SkRect& dst, 1114 const SkRect& dst,
1120 const SkPaint& srcPaint, 1115 const SkPaint& srcPaint,
1121 SkCanvas::SrcRectConstraint constraint) { 1116 SkCanvas::SrcRectConstraint constraint) {
1122 SkASSERT(false); 1117 SkASSERT(false);
1123 } 1118 }
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 fFontResources.push(newFont.get()); 2102 fFontResources.push(newFont.get());
2108 newFont.get()->ref(); 2103 newFont.get()->ref();
2109 } 2104 }
2110 return resourceIndex; 2105 return resourceIndex;
2111 } 2106 }
2112 2107
2113 static SkSize rect_to_size(const SkRect& r) { 2108 static SkSize rect_to_size(const SkRect& r) {
2114 return SkSize::Make(r.width(), r.height()); 2109 return SkSize::Make(r.width(), r.height());
2115 } 2110 }
2116 2111
2117 static const SkImage* color_filter(const SkImage* image, SkColorFilter* colorFil ter) { 2112 static sk_sp<SkImage> color_filter(const SkImageBitmap& imageBitmap,
2113 SkColorFilter* colorFilter) {
2118 sk_sp<SkSurface> surface(SkSurface::NewRaster( 2114 sk_sp<SkSurface> surface(SkSurface::NewRaster(
2119 SkImageInfo::MakeN32Premul(image->dimensions()))); 2115 SkImageInfo::MakeN32Premul(imageBitmap.dimensions())));
2120 if (!surface) { 2116 SkASSERT(surface);
2121 return image;
2122 }
2123 SkCanvas* canvas = surface->getCanvas(); 2117 SkCanvas* canvas = surface->getCanvas();
2124 canvas->clear(SK_ColorTRANSPARENT); 2118 canvas->clear(SK_ColorTRANSPARENT);
2125 SkPaint paint; 2119 SkPaint paint;
2126 paint.setColorFilter(sk_ref_sp(colorFilter)); 2120 paint.setColorFilter(sk_ref_sp(colorFilter));
2127 canvas->drawImage(image, 0, 0, &paint); 2121 imageBitmap.draw(canvas, &paint);
2128 canvas->flush(); 2122 canvas->flush();
2129 return surface->makeImageSnapshot().release(); 2123 return surface->makeImageSnapshot();
2130 } 2124 }
2131 2125
2132 //////////////////////////////////////////////////////////////////////////////// 2126 ////////////////////////////////////////////////////////////////////////////////
2133 void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, 2127 void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
2134 const SkClipStack* clipStack, 2128 const SkClipStack* clipStack,
2135 const SkRegion& origClipRegion, 2129 const SkRegion& origClipRegion,
2136 const SkImage* image, 2130 SkImageBitmap imageBitmap,
2137 const SkIRect* srcRect,
2138 const SkPaint& paint) { 2131 const SkPaint& paint) {
2139 SkASSERT(image); 2132 if (imageBitmap.dimensions().isZero()) {
2133 return;
2134 }
2140 #ifdef SK_PDF_IMAGE_STATS 2135 #ifdef SK_PDF_IMAGE_STATS
2141 gDrawImageCalls.fetch_add(1); 2136 gDrawImageCalls.fetch_add(1);
2142 #endif 2137 #endif
2143 SkMatrix matrix = origMatrix; 2138 SkMatrix matrix = origMatrix;
2144 SkRegion perspectiveBounds; 2139 SkRegion perspectiveBounds;
2145 const SkRegion* clipRegion = &origClipRegion; 2140 const SkRegion* clipRegion = &origClipRegion;
2146 sk_sp<const SkImage> autoImageUnref; 2141 sk_sp<SkImage> autoImageUnref;
2147 2142
2148 if (srcRect) {
2149 autoImageUnref = image->makeSubset(*srcRect);
2150 if (!autoImageUnref) {
2151 return;
2152 }
2153 image = autoImageUnref.get();
2154 }
2155 // Rasterize the bitmap using perspective in a new bitmap. 2143 // Rasterize the bitmap using perspective in a new bitmap.
2156 if (origMatrix.hasPerspective()) { 2144 if (origMatrix.hasPerspective()) {
2157 if (fRasterDpi == 0) { 2145 if (fRasterDpi == 0) {
2158 return; 2146 return;
2159 } 2147 }
2160 // Transform the bitmap in the new space, without taking into 2148 // Transform the bitmap in the new space, without taking into
2161 // account the initial transform. 2149 // account the initial transform.
2162 SkPath perspectiveOutline; 2150 SkPath perspectiveOutline;
2163 SkRect imageBounds = SkRect::Make(image->bounds()); 2151 SkRect imageBounds = SkRect::Make(imageBitmap.bounds());
2164 perspectiveOutline.addRect(imageBounds); 2152 perspectiveOutline.addRect(imageBounds);
2165 perspectiveOutline.transform(origMatrix); 2153 perspectiveOutline.transform(origMatrix);
2166 2154
2167 // TODO(edisonn): perf - use current clip too. 2155 // TODO(edisonn): perf - use current clip too.
2168 // Retrieve the bounds of the new shape. 2156 // Retrieve the bounds of the new shape.
2169 SkRect bounds = perspectiveOutline.getBounds(); 2157 SkRect bounds = perspectiveOutline.getBounds();
2170 2158
2171 // Transform the bitmap in the new space, taking into 2159 // Transform the bitmap in the new space, taking into
2172 // account the initial transform. 2160 // account the initial transform.
2173 SkMatrix total = origMatrix; 2161 SkMatrix total = origMatrix;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 SkScalar deltaX = bounds.left(); 2193 SkScalar deltaX = bounds.left();
2206 SkScalar deltaY = bounds.top(); 2194 SkScalar deltaY = bounds.top();
2207 2195
2208 SkMatrix offsetMatrix = origMatrix; 2196 SkMatrix offsetMatrix = origMatrix;
2209 offsetMatrix.postTranslate(-deltaX, -deltaY); 2197 offsetMatrix.postTranslate(-deltaX, -deltaY);
2210 offsetMatrix.postScale(scaleX, scaleY); 2198 offsetMatrix.postScale(scaleX, scaleY);
2211 2199
2212 // Translate the draw in the new canvas, so we perfectly fit the 2200 // Translate the draw in the new canvas, so we perfectly fit the
2213 // shape in the bitmap. 2201 // shape in the bitmap.
2214 canvas->setMatrix(offsetMatrix); 2202 canvas->setMatrix(offsetMatrix);
2215 canvas->drawImage(image, 0, 0, nullptr); 2203 imageBitmap.draw(canvas, nullptr);
2216 // Make sure the final bits are in the bitmap. 2204 // Make sure the final bits are in the bitmap.
2217 canvas->flush(); 2205 canvas->flush();
2218 2206
2219 // In the new space, we use the identity matrix translated 2207 // In the new space, we use the identity matrix translated
2220 // and scaled to reflect DPI. 2208 // and scaled to reflect DPI.
2221 matrix.setScale(1 / scaleX, 1 / scaleY); 2209 matrix.setScale(1 / scaleX, 1 / scaleY);
2222 matrix.postTranslate(deltaX, deltaY); 2210 matrix.postTranslate(deltaX, deltaY);
2223 2211
2224 perspectiveBounds.setRect(bounds.roundOut()); 2212 perspectiveBounds.setRect(bounds.roundOut());
2225 clipRegion = &perspectiveBounds; 2213 clipRegion = &perspectiveBounds;
2226 srcRect = nullptr;
2227 2214
2228 autoImageUnref.reset(surface->makeImageSnapshot().release()); 2215 autoImageUnref = surface->makeImageSnapshot();
2229 image = autoImageUnref.get(); 2216 imageBitmap = SkImageBitmap(autoImageUnref.get());
2230 } 2217 }
2231 2218
2232 SkMatrix scaled; 2219 SkMatrix scaled;
2233 // Adjust for origin flip. 2220 // Adjust for origin flip.
2234 scaled.setScale(SK_Scalar1, -SK_Scalar1); 2221 scaled.setScale(SK_Scalar1, -SK_Scalar1);
2235 scaled.postTranslate(0, SK_Scalar1); 2222 scaled.postTranslate(0, SK_Scalar1);
2236 // Scale the image up from 1x1 to WxH. 2223 // Scale the image up from 1x1 to WxH.
2237 SkIRect subset = image->bounds(); 2224 SkIRect subset = imageBitmap.bounds();
2238 scaled.postScale(SkIntToScalar(image->width()), 2225 scaled.postScale(SkIntToScalar(imageBitmap.dimensions().width()),
2239 SkIntToScalar(image->height())); 2226 SkIntToScalar(imageBitmap.dimensions().height()));
2240 scaled.postConcat(matrix); 2227 scaled.postConcat(matrix);
2241 ScopedContentEntry content(this, clipStack, *clipRegion, scaled, paint); 2228 ScopedContentEntry content(this, clipStack, *clipRegion, scaled, paint);
2242 if (!content.entry() || (srcRect && !subset.intersect(*srcRect))) { 2229 if (!content.entry()) {
2243 return; 2230 return;
2244 } 2231 }
2245 if (content.needShape()) { 2232 if (content.needShape()) {
2246 SkPath shape; 2233 SkPath shape;
2247 shape.addRect(SkRect::Make(subset)); 2234 shape.addRect(SkRect::Make(subset));
2248 shape.transform(matrix); 2235 shape.transform(matrix);
2249 content.setShape(shape); 2236 content.setShape(shape);
2250 } 2237 }
2251 if (!content.needSource()) { 2238 if (!content.needSource()) {
2252 return; 2239 return;
2253 } 2240 }
2254 2241
2255 if (SkColorFilter* colorFilter = paint.getColorFilter()) { 2242 if (SkColorFilter* colorFilter = paint.getColorFilter()) {
2256 // TODO(https://bug.skia.org/4378): implement colorfilter on other 2243 // TODO(https://bug.skia.org/4378): implement colorfilter on other
2257 // draw calls. This code here works for all 2244 // draw calls. This code here works for all
2258 // drawBitmap*()/drawImage*() calls amd ImageFilters (which 2245 // drawBitmap*()/drawImage*() calls amd ImageFilters (which
2259 // rasterize a layer on this backend). Fortuanely, this seems 2246 // rasterize a layer on this backend). Fortuanely, this seems
2260 // to be how Chromium impements most color-filters. 2247 // to be how Chromium impements most color-filters.
2261 autoImageUnref.reset(color_filter(image, colorFilter)); 2248 autoImageUnref = color_filter(imageBitmap, colorFilter);
2262 image = autoImageUnref.get(); 2249 imageBitmap = SkImageBitmap(autoImageUnref.get());
2263 // TODO(halcanary): de-dupe this by caching filtered images. 2250 // TODO(halcanary): de-dupe this by caching filtered images.
2264 // (maybe in the resource cache?) 2251 // (maybe in the resource cache?)
2265 } 2252 }
2266 sk_sp<SkPDFObject> pdfimage(SkSafeRef(fDocument->canon()->findPDFBitmap(imag e))); 2253
2254 SkBitmapKey key = imageBitmap.getKey();
2255 sk_sp<SkPDFObject> pdfimage = fDocument->canon()->findPDFBitmap(key);
2267 if (!pdfimage) { 2256 if (!pdfimage) {
2268 pdfimage.reset(SkPDFCreateBitmapObject( 2257 auto img = imageBitmap.makeImage();
2269 image, fDocument->canon()->getPixelSerializer())) ; 2258 if (!img) {
2259 return;
2260 }
2261 pdfimage = SkPDFCreateBitmapObject(
2262 std::move(img), fDocument->canon()->getPixelSerializer());
2270 if (!pdfimage) { 2263 if (!pdfimage) {
2271 return; 2264 return;
2272 } 2265 }
2273 #if SK_PDF_SERIALIZE_IMAGES_EARLY // TODO(halcanary): enable. 2266 fDocument->serialize(pdfimage); // serialize images early.
2274 sk_sp<SkData> encodedImage(image->refEncodedData()); 2267 fDocument->canon()->addPDFBitmap(key, pdfimage);
2275 if (!encodedImage) {
2276 fDocument->serialize(pdfimage);
2277 }
2278 #endif
2279 fDocument->canon()->addPDFBitmap(image->uniqueID(), pdfimage.get());
2280 } 2268 }
2269 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject>
2281 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), 2270 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()),
2282 &content.entry()->fContent); 2271 &content.entry()->fContent);
2283 } 2272 }
OLDNEW
« src/pdf/SkBitmapKey.h ('K') | « src/pdf/SkPDFDevice.h ('k') | src/pdf/SkPDFDocument.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698