Merge frameworks/base changes from master-skia to master.

Adaptations to changes in Skia upstream since Oct 2014.
(https://code.google.com/p/skia/issues/detail?id=2377)

cbb922d use new roundOut signature
77082de Call SkColorTable::readColors().
5456ab1 Handle the result of SkMatrix::asAffine.
25cfc78 Remove dependence on SK_LEGACY_PICTURE_SIZE_API.

BUG:18468293

Change-Id: I5a4d274e854298843891410b1ffd5e24f038b88a
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index f506569..1a29a62 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -224,37 +224,34 @@
                               SkColorTable* ctable) {
     SkASSERT(width > 0);
     const uint8_t* s = (const uint8_t*)src;
-    const SkPMColor* colors = ctable->lockColors();
+    const SkPMColor* colors = ctable->readColors();
     do {
         *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
     } while (--width != 0);
-    ctable->unlockColors();
 }
 
 static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
                               SkColorTable* ctable) {
     SkASSERT(width > 0);
     const uint8_t* s = (const uint8_t*)src;
-    const SkPMColor* colors = ctable->lockColors();
+    const SkPMColor* colors = ctable->readColors();
     do {
         SkPMColor c = colors[*s++];
         *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
                                 SkGetPackedG32(c), SkGetPackedB32(c));
     } while (--width != 0);
-    ctable->unlockColors();
 }
 
 static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
                                SkColorTable* ctable) {
     SkASSERT(width > 0);
     const uint8_t* s = (const uint8_t*)src;
-    const SkPMColor* colors = ctable->lockColors();
+    const SkPMColor* colors = ctable->readColors();
     do {
         SkPMColor c = colors[*s++];
         *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
                                SkGetPackedB32(c));
     } while (--width != 0);
-    ctable->unlockColors();
 }
 
 // can return NULL
@@ -639,8 +636,7 @@
             int count = ctable->count();
             p->writeInt32(count);
             memcpy(p->writeInplace(count * sizeof(SkPMColor)),
-                   ctable->lockColors(), count * sizeof(SkPMColor));
-            ctable->unlockColors();
+                   ctable->readColors(), count * sizeof(SkPMColor));
         } else {
             p->writeInt32(0);   // indicate no ctable
         }
@@ -827,10 +823,8 @@
             return JNI_FALSE;
         }
 
-        SkAutoLockColors alc0(ct0);
-        SkAutoLockColors alc1(ct1);
         const size_t size = ct0->count() * sizeof(SkPMColor);
-        if (memcmp(alc0.colors(), alc1.colors(), size) != 0) {
+        if (memcmp(ct0->readColors(), ct1->readColors(), size) != 0) {
             return JNI_FALSE;
         }
     }
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 2ec0828..8e1e8d3 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -8,7 +8,6 @@
 #include "SkCanvas.h"
 #include "SkDevice.h"
 #include "SkMath.h"
-#include "SkPicture.h"
 #include "SkRegion.h"
 #include <android_runtime/AndroidRuntime.h>
 
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index 33d43083..c249012 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -27,9 +27,10 @@
         mHeight = src->height();
         if (NULL != src->mPicture.get()) {
             mPicture.reset(SkRef(src->mPicture.get()));
-        } if (NULL != src->mRecorder.get()) {
+        } else if (NULL != src->mRecorder.get()) {
             mPicture.reset(src->makePartialCopy());
         }
+        validate();
     } else {
         mWidth = 0;
         mHeight = 0;
@@ -48,35 +49,31 @@
 void Picture::endRecording() {
     if (NULL != mRecorder.get()) {
         mPicture.reset(mRecorder->endRecording());
+        validate();
         mRecorder.reset(NULL);
     }
 }
 
 int Picture::width() const {
-    if (NULL != mPicture.get()) {
-        SkASSERT(mPicture->width() == mWidth);
-        SkASSERT(mPicture->height() == mHeight);
-    }
-
+    validate();
     return mWidth;
 }
 
 int Picture::height() const {
-    if (NULL != mPicture.get()) {
-        SkASSERT(mPicture->width() == mWidth);
-        SkASSERT(mPicture->height() == mHeight);
-    }
-
+    validate();
     return mHeight;
 }
 
 Picture* Picture::CreateFromStream(SkStream* stream) {
     Picture* newPict = new Picture;
 
-    newPict->mPicture.reset(SkPicture::CreateFromStream(stream));
-    if (NULL != newPict->mPicture.get()) {
-        newPict->mWidth = newPict->mPicture->width();
-        newPict->mHeight = newPict->mPicture->height();
+    SkPicture* skPicture = SkPicture::CreateFromStream(stream);
+    if (NULL != skPicture) {
+        newPict->mPicture.reset(skPicture);
+
+        const SkIRect cullRect = skPicture->cullRect().roundOut();
+        newPict->mWidth = cullRect.width();
+        newPict->mHeight = cullRect.height();
     }
 
     return newPict;
@@ -87,6 +84,7 @@
         SkAutoTDelete<SkPicture> tempPict(this->makePartialCopy());
         tempPict->serialize(stream);
     } else if (NULL != mPicture.get()) {
+        validate();
         mPicture->serialize(stream);
     } else {
         SkPictureRecorder recorder;
@@ -101,6 +99,7 @@
         this->endRecording();
         SkASSERT(NULL != mPicture.get());
     }
+    validate();
     if (NULL != mPicture.get()) {
         mPicture.get()->playback(canvas->getSkCanvas());
     }
@@ -116,4 +115,14 @@
     return reRecorder.endRecording();
 }
 
+void Picture::validate() const {
+#ifdef SK_DEBUG
+    if (NULL != mPicture.get()) {
+        SkRect cullRect = mPicture->cullRect();
+        SkRect myRect = SkRect::MakeWH(SkIntToScalar(mWidth), SkIntToScalar(mHeight));
+        SkASSERT(cullRect == myRect);
+    }
+#endif
+}
+
 }; // namespace android
diff --git a/core/jni/android/graphics/Picture.h b/core/jni/android/graphics/Picture.h
index 4db923d..a9db648 100644
--- a/core/jni/android/graphics/Picture.h
+++ b/core/jni/android/graphics/Picture.h
@@ -60,6 +60,8 @@
     // Make a copy of a picture that is in the midst of being recorded. The
     // resulting picture will have balanced saves and restores.
     SkPicture* makePartialCopy() const;
+
+    void validate() const;
 };
 
 }; // namespace android
diff --git a/core/jni/android/graphics/pdf/PdfDocument.cpp b/core/jni/android/graphics/pdf/PdfDocument.cpp
index 8ba164f..a91b15b 100644
--- a/core/jni/android/graphics/pdf/PdfDocument.cpp
+++ b/core/jni/android/graphics/pdf/PdfDocument.cpp
@@ -71,7 +71,7 @@
         mCurrentPage = page;
 
         SkCanvas* canvas = page->mPictureRecorder->beginRecording(
-                contentRect.width(), contentRect.height(), NULL, 0);
+                SkRect::MakeWH(contentRect.width(), contentRect.height()));
 
         return canvas;
     }
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
index cb228f2..84434ae 100644
--- a/core/jni/android/graphics/pdf/PdfEditor.cpp
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -201,7 +201,11 @@
     SkMatrix* skTransform = reinterpret_cast<SkMatrix*>(transformPtr);
 
     SkScalar transformValues[6];
-    skTransform->asAffine(transformValues);
+    if (!skTransform->asAffine(transformValues)) {
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                "transform matrix has perspective. Only affine matrices are allowed.");
+        return;
+    }
 
     // PDF's coordinate system origin is left-bottom while in graphics it
     // is the top-left. So, translate the PDF coordinates to ours.
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index ae23cb4..fc98cf9 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -219,11 +219,16 @@
         matrix.Set(1, 0, 0, -1, 0, pPage->GetPageHeight());
 
         SkScalar transformValues[6];
-        transform->asAffine(transformValues);
+        if (transform->asAffine(transformValues)) {
+            matrix.Concat(transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
+                    transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
+                    transformValues[SkMatrix::kATransX], transformValues[SkMatrix::kATransY]);
+        } else {
+            // Already checked for a return value of false in the caller, so this should never
+            // happen.
+            ALOGE("Error rendering page!");
+        }
 
-        matrix.Concat(transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
-                transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
-                transformValues[SkMatrix::kATransX], transformValues[SkMatrix::kATransY]);
     }
     pageContext->AppendObjectList(pPage, &matrix);
 
@@ -264,6 +269,12 @@
         renderFlags |= FPDF_PRINTING;
     }
 
+    if (skMatrix && !skMatrix->asAffine(NULL)) {
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                "transform matrix has perspective. Only affine matrices are allowed.");
+        return;
+    }
+
     renderPageBitmap(bitmap, page, destLeft, destTop, destRight,
             destBottom, skMatrix, renderFlags);
 
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index da30044..461507f 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -675,9 +675,8 @@
         if (data) {
             void* const pixels = (char*)data + palette_size;
             SkColorTable* ctable = bitmap.getColorTable();
-            memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
+            memcpy(data, ctable->readColors(), ctable->count() * sizeof(SkPMColor));
             memcpy(pixels, p, size);
-            ctable->unlockColors();
             glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
             free(data);
         } else {
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index a422622..9bd3bdc 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -222,7 +222,7 @@
     LOG_ALWAYS_FATAL_IF(mHead->prev != mHead, "Cannot finish, mismatched push/pop calls! %p vs. %p", mHead->prev, mHead);
     // Root node never has a transform, so this is the fully mapped dirty rect
     *totalDirty = mHead->pendingDirty;
-    totalDirty->roundOut();
+    totalDirty->roundOut(totalDirty);
     mHead->pendingDirty.setEmpty();
 }
 
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index b448949..5a7ea40 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -223,7 +223,7 @@
     }
 
     if (dirty.intersect(0, 0, getWidth(), getHeight())) {
-        dirty.roundOut();
+        dirty.roundOut(&dirty);
         mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom);
     }
     // This is not inside the above if because we may have called