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

Side by Side Diff: src/core/SkPictureRecord.cpp

Issue 715423003: Restore bitmap dedup in SkPictureRecord. Cuts RAM usage of DM by half. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 6 years, 1 month 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/core/SkPictureRecord.h ('k') | no next file » | 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 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 "SkPictureRecord.h" 8 #include "SkPictureRecord.h"
9 #include "SkDevice.h" 9 #include "SkDevice.h"
10 #include "SkPatchUtils.h" 10 #include "SkPatchUtils.h"
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 893
894 this->validate(initialOffset, size); 894 this->validate(initialOffset, size);
895 } 895 }
896 896
897 /////////////////////////////////////////////////////////////////////////////// 897 ///////////////////////////////////////////////////////////////////////////////
898 898
899 SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfac eProps&) { 899 SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfac eProps&) {
900 return NULL; 900 return NULL;
901 } 901 }
902 902
903 int SkPictureRecord::addBitmap(const SkBitmap& bitmap) { 903 // If we already have a stored, can we reuse it instead of also storing b?
904 static bool equivalent(const SkBitmap& a, const SkBitmap& b) {
905 if (a.info() != b.info() || a.pixelRefOrigin() != b.pixelRefOrigin()) {
906 // Requiring a.info() == b.info() may be overkill in some cases (alphaty pe mismatch),
907 // but it sure makes things easier to reason about below.
908 return false;
909 }
910 if (a.pixelRef() == b.pixelRef()) {
911 return true; // Same shape and same pixels -> same bitmap.
912 }
913
914 // From here down we're going to have to look at the bitmap data, so we requ ire pixelRefs().
915 if (!a.pixelRef() || !b.pixelRef()) {
916 return false;
917 }
918
919 // If the bitmaps have encoded data, check first before locking pixels so th ey don't decode.
920 SkAutoTUnref<SkData> encA(a.pixelRef()->refEncodedData()),
921 encB(b.pixelRef()->refEncodedData());
922 if (encA && encB) {
923 return encA->equals(encB);
924 } else if (encA || encB) {
925 return false; // One has encoded data but the other does not.
926 }
927
928 // As a last resort, we have to look at the pixels. This will read back tex tures.
929 SkAutoLockPixels al(a), bl(b);
930 const char* ap = (const char*)a.getPixels();
931 const char* bp = (const char*)b.getPixels();
932 if (ap && bp) {
933 // We check row by row; row bytes might differ.
934 SkASSERT(a.info() == b.info()); // We checked this above.
935 SkASSERT(a.info().bytesPerPixel() > 0); // If we have pixelRefs, this b etter be true.
936 const SkImageInfo info = a.info();
937 const size_t bytesToCompare = info.width() * info.bytesPerPixel();
938 for (int row = 0; row < info.height(); row++) {
939 if (0 != memcmp(ap, bp, bytesToCompare)) {
940 return false;
941 }
942 ap += a.rowBytes();
943 bp += b.rowBytes();
944 }
945 return true;
946 }
947 return false; // Couldn't get pixels for both bitmaps.
948 }
949
950 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
951 // First see if we already have this bitmap. This deduplication should real ly
952 // only be important for our tests, where bitmaps tend not to be tagged immu table.
953 // In Chrome (and hopefully Android?) they're typically immutable.
scroggo 2015/08/06 18:54:40 Alas, no, on Android, there is no Java API to make
954 for (int i = 0; i < fBitmaps.count(); i++) {
955 if (equivalent(fBitmaps[i], bitmap)) {
956 this->addInt(i); // Unlike the rest, bitmap indices are 0-based.
957 return;
958 }
959 }
960 // Don't have it. We'll add it to our list, making sure it's tagged as immu table.
904 if (bitmap.isImmutable()) { 961 if (bitmap.isImmutable()) {
962 // Shallow copies of bitmaps are cheap, so immutable == fast.
905 fBitmaps.push_back(bitmap); 963 fBitmaps.push_back(bitmap);
906 } else { 964 } else {
965 // If you see this block on a memory profile, it's a good opportunity to reduce RAM usage.
907 SkBitmap copy; 966 SkBitmap copy;
908 bitmap.copyTo(&copy); 967 bitmap.copyTo(&copy);
909 copy.setImmutable(); 968 copy.setImmutable();
910 fBitmaps.push_back(copy); 969 fBitmaps.push_back(copy);
911 } 970 }
912 this->addInt(fBitmaps.count()-1); // Unlike the rest, bitmap indicies are 0 -based. 971 this->addInt(fBitmaps.count()-1); // Remember, 0-based.
913 return fBitmaps.count();
914 } 972 }
915 973
916 void SkPictureRecord::addMatrix(const SkMatrix& matrix) { 974 void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
917 fWriter.writeMatrix(matrix); 975 fWriter.writeMatrix(matrix);
918 } 976 }
919 977
920 void SkPictureRecord::addPaintPtr(const SkPaint* paint) { 978 void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
921 fContentInfo.onAddPaintPtr(paint); 979 fContentInfo.onAddPaintPtr(paint);
922 980
923 if (paint) { 981 if (paint) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 void SkPictureRecord::addTextBlob(const SkTextBlob *blob) { 1060 void SkPictureRecord::addTextBlob(const SkTextBlob *blob) {
1003 int index = fTextBlobRefs.count(); 1061 int index = fTextBlobRefs.count();
1004 *fTextBlobRefs.append() = blob; 1062 *fTextBlobRefs.append() = blob;
1005 blob->ref(); 1063 blob->ref();
1006 // follow the convention of recording a 1-based index 1064 // follow the convention of recording a 1-based index
1007 this->addInt(index + 1); 1065 this->addInt(index + 1);
1008 } 1066 }
1009 1067
1010 /////////////////////////////////////////////////////////////////////////////// 1068 ///////////////////////////////////////////////////////////////////////////////
1011 1069
OLDNEW
« no previous file with comments | « src/core/SkPictureRecord.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698