Changes to framework for ToT Skia.

Consists of 3 cherry-pick from changes by robertphillips@google.com
in master-skia:

-----------------------------------------------------------------------

New AndroidPicture wrapper class

Address code review comments & use new SkPictureRecorder::partialReplay
entry point

Addressing code review issues

Switch MakePartialCopy to makePartialCopy

Conflicts:
	core/jni/android/graphics/Picture.cpp

Ie530ab15b3d549f0ecfb0ecc131f9144a7b72a91

Remove AndroidPicture from GraphicsJNI and split into .h and .cpp

-----------------------------------------------------------------------

Fix lingering legacy picture recording behavior
Address code review issues

Iaf870c2c400dbe70dc32d6d445574904f5ea718f

-----------------------------------------------------------------------

Update Android to new SkCanvas::drawPicture interface

As of Skia 9b14f26d (Alter SkCanvas::drawPicture (devirtualize,
take const SkPicture, take pointer) -
https://codereview.chromium.org/313613004) SkCanvas::drawPicture
has an alternate signature. The old entry point is deprecated.

I63395da61ecc3b58bfd2bc094752081f4b2f7535

-----------------------------------------------------------------------

Change-Id: I041133aeb5639abd853370e512acf93870f82aea
This commit is contained in:
Robert Phillips
2014-04-23 12:31:37 -04:00
committed by Leon Scroggins III
parent 85a7bb169b
commit b59508fce5
7 changed files with 219 additions and 33 deletions

View File

@@ -89,6 +89,7 @@ LOCAL_SRC_FILES:= \
android_util_Process.cpp \
android_util_StringBlock.cpp \
android_util_XmlBlock.cpp \
android/graphics/AndroidPicture.cpp \
android/graphics/AutoDecodeCancel.cpp \
android/graphics/Bitmap.cpp \
android/graphics/BitmapFactory.cpp \

View File

@@ -0,0 +1,112 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "AndroidPicture.h"
#include "SkCanvas.h"
#include "SkStream.h"
AndroidPicture::AndroidPicture(const AndroidPicture* src) {
if (NULL != src) {
mWidth = src->width();
mHeight = src->height();
if (NULL != src->mPicture.get()) {
mPicture.reset(SkRef(src->mPicture.get()));
} if (NULL != src->mRecorder.get()) {
mPicture.reset(src->makePartialCopy());
}
} else {
mWidth = 0;
mHeight = 0;
}
}
SkCanvas* AndroidPicture::beginRecording(int width, int height) {
mPicture.reset(NULL);
mRecorder.reset(new SkPictureRecorder);
mWidth = width;
mHeight = height;
return mRecorder->beginRecording(width, height, NULL, 0);
}
void AndroidPicture::endRecording() {
if (NULL != mRecorder.get()) {
mPicture.reset(mRecorder->endRecording());
mRecorder.reset(NULL);
}
}
int AndroidPicture::width() const {
if (NULL != mPicture.get()) {
SkASSERT(mPicture->width() == mWidth);
SkASSERT(mPicture->height() == mHeight);
}
return mWidth;
}
int AndroidPicture::height() const {
if (NULL != mPicture.get()) {
SkASSERT(mPicture->width() == mWidth);
SkASSERT(mPicture->height() == mHeight);
}
return mHeight;
}
AndroidPicture* AndroidPicture::CreateFromStream(SkStream* stream) {
AndroidPicture* newPict = new AndroidPicture;
newPict->mPicture.reset(SkPicture::CreateFromStream(stream));
if (NULL != newPict->mPicture.get()) {
newPict->mWidth = newPict->mPicture->width();
newPict->mHeight = newPict->mPicture->height();
}
return newPict;
}
void AndroidPicture::serialize(SkWStream* stream) const {
if (NULL != mRecorder.get()) {
SkAutoTDelete<SkPicture> tempPict(this->makePartialCopy());
tempPict->serialize(stream);
} else if (NULL != mPicture.get()) {
mPicture->serialize(stream);
} else {
SkPicture empty;
empty.serialize(stream);
}
}
void AndroidPicture::draw(SkCanvas* canvas) {
if (NULL != mRecorder.get()) {
this->endRecording();
SkASSERT(NULL != mPicture.get());
}
if (NULL != mPicture.get()) {
// TODO: remove this const_cast once pictures are immutable
const_cast<SkPicture*>(mPicture.get())->draw(canvas);
}
}
SkPicture* AndroidPicture::makePartialCopy() const {
SkASSERT(NULL != mRecorder.get());
SkPictureRecorder reRecorder;
SkCanvas* canvas = reRecorder.beginRecording(mWidth, mHeight, NULL, 0);
mRecorder->partialReplay(canvas);
return reRecorder.endRecording();
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_PICTURE_H
#define ANDROID_PICTURE_H
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkRefCnt.h"
#include "SkTemplates.h"
class SkCanvas;
class SkPicture;
class SkPictureRecorder;
class SkStream;
class SkWStream;
// Skia's SkPicture class has been split into an SkPictureRecorder
// and an SkPicture. AndroidPicture recreates the functionality
// of the old SkPicture interface by flip-flopping between the two
// new classes.
class AndroidPicture {
public:
explicit AndroidPicture(const AndroidPicture* src = NULL);
SkCanvas* beginRecording(int width, int height);
void endRecording();
int width() const;
int height() const;
static AndroidPicture* CreateFromStream(SkStream* stream);
void serialize(SkWStream* stream) const;
void draw(SkCanvas* canvas);
private:
int mWidth;
int mHeight;
SkAutoTUnref<const SkPicture> mPicture;
SkAutoTDelete<SkPictureRecorder> mRecorder;
// 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;
};
#endif // ANDROID_PICTURE_H

View File

@@ -3,6 +3,7 @@
#include "jni.h"
#include "JNIHelp.h"
#include "GraphicsJNI.h"
#include "AndroidPicture.h"
#include "SkCanvas.h"
#include "SkDevice.h"
@@ -345,13 +346,13 @@ android::TypefaceImpl* GraphicsJNI::getNativeTypeface(JNIEnv* env, jobject paint
return p;
}
SkPicture* GraphicsJNI::getNativePicture(JNIEnv* env, jobject picture)
AndroidPicture* GraphicsJNI::getNativePicture(JNIEnv* env, jobject picture)
{
SkASSERT(env);
SkASSERT(picture);
SkASSERT(env->IsInstanceOf(picture, gPicture_class));
jlong pictureHandle = env->GetLongField(picture, gPicture_nativeInstanceID);
SkPicture* p = reinterpret_cast<SkPicture*>(pictureHandle);
AndroidPicture* p = reinterpret_cast<AndroidPicture*>(pictureHandle);
SkASSERT(p);
return p;
}

View File

@@ -14,7 +14,7 @@
class SkBitmapRegionDecoder;
class SkCanvas;
class SkPaint;
class SkPicture;
class AndroidPicture;
class GraphicsJNI {
public:
@@ -50,7 +50,7 @@ public:
static SkPaint* getNativePaint(JNIEnv*, jobject paint);
static android::TypefaceImpl* getNativeTypeface(JNIEnv*, jobject paint);
static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
static SkPicture* getNativePicture(JNIEnv*, jobject picture);
static AndroidPicture* getNativePicture(JNIEnv*, jobject picture);
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
// Given the 'native' long held by the Rasterizer.java object, return a

View File

@@ -17,9 +17,9 @@
#include "jni.h"
#include "GraphicsJNI.h"
#include <android_runtime/AndroidRuntime.h>
#include "AndroidPicture.h"
#include "SkCanvas.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkTemplates.h"
#include "CreateJavaOutputStreamAdaptor.h"
@@ -29,45 +29,41 @@ namespace android {
class SkPictureGlue {
public:
static jlong newPicture(JNIEnv* env, jobject, jlong srcHandle) {
const SkPicture* src = reinterpret_cast<SkPicture*>(srcHandle);
if (src) {
return reinterpret_cast<jlong>(new SkPicture(*src));
} else {
return reinterpret_cast<jlong>(new SkPicture);
}
const AndroidPicture* src = reinterpret_cast<AndroidPicture*>(srcHandle);
return reinterpret_cast<jlong>(new AndroidPicture(src));
}
static jlong deserialize(JNIEnv* env, jobject, jobject jstream,
jbyteArray jstorage) {
SkPicture* picture = NULL;
AndroidPicture* picture = NULL;
SkStream* strm = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
if (strm) {
picture = SkPicture::CreateFromStream(strm);
picture = AndroidPicture::CreateFromStream(strm);
delete strm;
}
return reinterpret_cast<jlong>(picture);
}
static void killPicture(JNIEnv* env, jobject, jlong pictureHandle) {
SkPicture* picture = reinterpret_cast<SkPicture*>(pictureHandle);
AndroidPicture* picture = reinterpret_cast<AndroidPicture*>(pictureHandle);
SkASSERT(picture);
picture->unref();
delete picture;
}
static void draw(JNIEnv* env, jobject, jlong canvasHandle,
jlong pictureHandle) {
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(canvasHandle);
SkPicture* picture = reinterpret_cast<SkPicture*>(pictureHandle);
AndroidPicture* picture = reinterpret_cast<AndroidPicture*>(pictureHandle);
SkASSERT(canvas);
SkASSERT(picture);
picture->draw(canvas);
}
static jboolean serialize(JNIEnv* env, jobject, jlong pictureHandle,
jobject jstream, jbyteArray jstorage) {
SkPicture* picture = reinterpret_cast<SkPicture*>(pictureHandle);
jobject jstream, jbyteArray jstorage) {
AndroidPicture* picture = reinterpret_cast<AndroidPicture*>(pictureHandle);
SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
if (NULL != strm) {
picture->serialize(strm);
delete strm;
@@ -78,19 +74,21 @@ public:
static jint getWidth(JNIEnv* env, jobject jpic) {
NPE_CHECK_RETURN_ZERO(env, jpic);
int width = GraphicsJNI::getNativePicture(env, jpic)->width();
AndroidPicture* pict = GraphicsJNI::getNativePicture(env, jpic);
int width = pict->width();
return static_cast<jint>(width);
}
static jint getHeight(JNIEnv* env, jobject jpic) {
NPE_CHECK_RETURN_ZERO(env, jpic);
int height = GraphicsJNI::getNativePicture(env, jpic)->height();
AndroidPicture* pict = GraphicsJNI::getNativePicture(env, jpic);
int height = pict->height();
return static_cast<jint>(height);
}
static jlong beginRecording(JNIEnv* env, jobject, jlong pictHandle,
jint w, jint h) {
SkPicture* pict = reinterpret_cast<SkPicture*>(pictHandle);
jint w, jint h) {
AndroidPicture* pict = reinterpret_cast<AndroidPicture*>(pictHandle);
// beginRecording does not ref its return value, it just returns it.
SkCanvas* canvas = pict->beginRecording(w, h);
// the java side will wrap this guy in a Canvas.java, which will call
@@ -101,7 +99,7 @@ public:
}
static void endRecording(JNIEnv* env, jobject, jlong pictHandle) {
SkPicture* pict = reinterpret_cast<SkPicture*>(pictHandle);
AndroidPicture* pict = reinterpret_cast<AndroidPicture*>(pictHandle);
pict->endRecording();
}
};

View File

@@ -24,6 +24,7 @@
#include "SkCanvas.h"
#include "SkDocument.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkStream.h"
#include "SkRect.h"
@@ -32,15 +33,22 @@ namespace android {
struct PageRecord {
PageRecord(int width, int height, const SkRect& contentRect)
: mPicture(new SkPicture()), mWidth(width), mHeight(height) {
: mPictureRecorder(new SkPictureRecorder())
, mPicture(NULL)
, mWidth(width)
, mHeight(height) {
mContentRect = contentRect;
}
~PageRecord() {
mPicture->unref();
delete mPictureRecorder;
if (NULL != mPicture) {
mPicture->unref();
}
}
SkPicture* const mPicture;
SkPictureRecorder* mPictureRecorder;
SkPicture* mPicture;
const int mWidth;
const int mHeight;
SkRect mContentRect;
@@ -62,8 +70,8 @@ public:
mPages.push_back(page);
mCurrentPage = page;
SkCanvas* canvas = page->mPicture->beginRecording(
contentRect.width(), contentRect.height(), 0);
SkCanvas* canvas = page->mPictureRecorder->beginRecording(
contentRect.width(), contentRect.height(), NULL, 0);
// We pass this canvas to Java where it is used to construct
// a Java Canvas object which dereferences the pointer when it
@@ -75,7 +83,11 @@ public:
void finishPage() {
assert(mCurrentPage != NULL);
mCurrentPage->mPicture->endRecording();
assert(mCurrentPage->mPictureRecorder != NULL);
assert(mCurrentPage->mPicture == NULL);
mCurrentPage->mPicture = mCurrentPage->mPictureRecorder->endRecording();
delete mCurrentPage->mPictureRecorder;
mCurrentPage->mPictureRecorder = NULL;
mCurrentPage = NULL;
}
@@ -89,7 +101,7 @@ public:
canvas->clipRect(page->mContentRect);
canvas->translate(page->mContentRect.left(), page->mContentRect.top());
canvas->drawPicture(*page->mPicture);
canvas->drawPicture(page->mPicture);
document->endPage();
}
@@ -97,11 +109,10 @@ public:
}
void close() {
assert(NULL == mCurrentPage);
for (unsigned i = 0; i < mPages.size(); i++) {
delete mPages[i];
}
delete mCurrentPage;
mCurrentPage = NULL;
}
private: