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:
committed by
Leon Scroggins III
parent
85a7bb169b
commit
b59508fce5
@@ -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 \
|
||||
|
||||
112
core/jni/android/graphics/AndroidPicture.cpp
Normal file
112
core/jni/android/graphics/AndroidPicture.cpp
Normal 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();
|
||||
}
|
||||
63
core/jni/android/graphics/AndroidPicture.h
Normal file
63
core/jni/android/graphics/AndroidPicture.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user