summaryrefslogtreecommitdiff
path: root/libs/hwui/apex
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/apex')
-rw-r--r--libs/hwui/apex/LayoutlibLoader.cpp191
-rw-r--r--libs/hwui/apex/TypeCast.h70
-rw-r--r--libs/hwui/apex/android_bitmap.cpp304
-rw-r--r--libs/hwui/apex/android_canvas.cpp109
-rw-r--r--libs/hwui/apex/android_matrix.cpp37
-rw-r--r--libs/hwui/apex/android_paint.cpp47
-rw-r--r--libs/hwui/apex/android_region.cpp60
-rw-r--r--libs/hwui/apex/include/android/graphics/bitmap.h146
-rw-r--r--libs/hwui/apex/include/android/graphics/canvas.h142
-rw-r--r--libs/hwui/apex/include/android/graphics/jni_runtime.h35
-rw-r--r--libs/hwui/apex/include/android/graphics/matrix.h39
-rw-r--r--libs/hwui/apex/include/android/graphics/paint.h67
-rw-r--r--libs/hwui/apex/include/android/graphics/region.h77
-rw-r--r--libs/hwui/apex/include/android/graphics/renderthread.h34
-rw-r--r--libs/hwui/apex/jni_runtime.cpp177
-rw-r--r--libs/hwui/apex/renderthread.cpp25
16 files changed, 1560 insertions, 0 deletions
diff --git a/libs/hwui/apex/LayoutlibLoader.cpp b/libs/hwui/apex/LayoutlibLoader.cpp
new file mode 100644
index 000000000000..4bbf1214bdcf
--- /dev/null
+++ b/libs/hwui/apex/LayoutlibLoader.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2020 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 "graphics_jni_helpers.h"
+
+#include <GraphicsJNI.h>
+#include <SkGraphics.h>
+
+#include <sstream>
+#include <iostream>
+#include <unicode/putil.h>
+#include <unordered_map>
+#include <vector>
+
+using namespace std;
+
+/*
+ * This is responsible for setting up the JNI environment for communication between
+ * the Java and native parts of layoutlib, including registering native methods.
+ * This is mostly achieved by copying the way it is done in the platform
+ * (see AndroidRuntime.cpp).
+ */
+
+static JavaVM* javaVM;
+
+extern int register_android_graphics_Bitmap(JNIEnv*);
+extern int register_android_graphics_BitmapFactory(JNIEnv*);
+extern int register_android_graphics_ByteBufferStreamAdaptor(JNIEnv* env);
+extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env);
+extern int register_android_graphics_Graphics(JNIEnv* env);
+extern int register_android_graphics_ImageDecoder(JNIEnv*);
+extern int register_android_graphics_Interpolator(JNIEnv* env);
+extern int register_android_graphics_MaskFilter(JNIEnv* env);
+extern int register_android_graphics_NinePatch(JNIEnv*);
+extern int register_android_graphics_PathEffect(JNIEnv* env);
+extern int register_android_graphics_Shader(JNIEnv* env);
+extern int register_android_graphics_Typeface(JNIEnv* env);
+
+namespace android {
+
+extern int register_android_graphics_Canvas(JNIEnv* env);
+extern int register_android_graphics_ColorFilter(JNIEnv* env);
+extern int register_android_graphics_ColorSpace(JNIEnv* env);
+extern int register_android_graphics_DrawFilter(JNIEnv* env);
+extern int register_android_graphics_FontFamily(JNIEnv* env);
+extern int register_android_graphics_Matrix(JNIEnv* env);
+extern int register_android_graphics_Paint(JNIEnv* env);
+extern int register_android_graphics_Path(JNIEnv* env);
+extern int register_android_graphics_PathMeasure(JNIEnv* env);
+extern int register_android_graphics_Picture(JNIEnv* env);
+//extern int register_android_graphics_Region(JNIEnv* env);
+extern int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env);
+extern int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env);
+extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
+extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
+extern int register_android_graphics_fonts_Font(JNIEnv* env);
+extern int register_android_graphics_fonts_FontFamily(JNIEnv* env);
+extern int register_android_graphics_text_LineBreaker(JNIEnv* env);
+extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
+extern int register_android_util_PathParser(JNIEnv* env);
+extern int register_android_view_RenderNode(JNIEnv* env);
+extern int register_android_view_DisplayListCanvas(JNIEnv* env);
+
+#define REG_JNI(name) { name }
+struct RegJNIRec {
+ int (*mProc)(JNIEnv*);
+};
+
+// Map of all possible class names to register to their corresponding JNI registration function pointer
+// The actual list of registered classes will be determined at runtime via the 'native_classes' System property
+static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
+ {"android.graphics.Bitmap", REG_JNI(register_android_graphics_Bitmap)},
+ {"android.graphics.BitmapFactory", REG_JNI(register_android_graphics_BitmapFactory)},
+ {"android.graphics.ByteBufferStreamAdaptor",
+ REG_JNI(register_android_graphics_ByteBufferStreamAdaptor)},
+ {"android.graphics.Canvas", REG_JNI(register_android_graphics_Canvas)},
+ {"android.graphics.RenderNode", REG_JNI(register_android_view_RenderNode)},
+ {"android.graphics.ColorFilter", REG_JNI(register_android_graphics_ColorFilter)},
+ {"android.graphics.ColorSpace", REG_JNI(register_android_graphics_ColorSpace)},
+ {"android.graphics.CreateJavaOutputStreamAdaptor",
+ REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor)},
+ {"android.graphics.DrawFilter", REG_JNI(register_android_graphics_DrawFilter)},
+ {"android.graphics.FontFamily", REG_JNI(register_android_graphics_FontFamily)},
+ {"android.graphics.Graphics", REG_JNI(register_android_graphics_Graphics)},
+ {"android.graphics.ImageDecoder", REG_JNI(register_android_graphics_ImageDecoder)},
+ {"android.graphics.Interpolator", REG_JNI(register_android_graphics_Interpolator)},
+ {"android.graphics.MaskFilter", REG_JNI(register_android_graphics_MaskFilter)},
+ {"android.graphics.Matrix", REG_JNI(register_android_graphics_Matrix)},
+ {"android.graphics.NinePatch", REG_JNI(register_android_graphics_NinePatch)},
+ {"android.graphics.Paint", REG_JNI(register_android_graphics_Paint)},
+ {"android.graphics.Path", REG_JNI(register_android_graphics_Path)},
+ {"android.graphics.PathEffect", REG_JNI(register_android_graphics_PathEffect)},
+ {"android.graphics.PathMeasure", REG_JNI(register_android_graphics_PathMeasure)},
+ {"android.graphics.Picture", REG_JNI(register_android_graphics_Picture)},
+ {"android.graphics.RecordingCanvas", REG_JNI(register_android_view_DisplayListCanvas)},
+// {"android.graphics.Region", REG_JNI(register_android_graphics_Region)},
+ {"android.graphics.Shader", REG_JNI(register_android_graphics_Shader)},
+ {"android.graphics.Typeface", REG_JNI(register_android_graphics_Typeface)},
+ {"android.graphics.animation.NativeInterpolatorFactory",
+ REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory)},
+ {"android.graphics.animation.RenderNodeAnimator",
+ REG_JNI(register_android_graphics_animation_RenderNodeAnimator)},
+ {"android.graphics.drawable.AnimatedVectorDrawable",
+ REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable)},
+ {"android.graphics.drawable.VectorDrawable",
+ REG_JNI(register_android_graphics_drawable_VectorDrawable)},
+ {"android.graphics.fonts.Font", REG_JNI(register_android_graphics_fonts_Font)},
+ {"android.graphics.fonts.FontFamily", REG_JNI(register_android_graphics_fonts_FontFamily)},
+ {"android.graphics.text.LineBreaker", REG_JNI(register_android_graphics_text_LineBreaker)},
+ {"android.graphics.text.MeasuredText",
+ REG_JNI(register_android_graphics_text_MeasuredText)},
+ {"android.util.PathParser", REG_JNI(register_android_util_PathParser)},
+};
+
+static int register_jni_procs(const std::unordered_map<std::string, RegJNIRec>& jniRegMap,
+ const vector<string>& classesToRegister, JNIEnv* env) {
+
+ for (const string& className : classesToRegister) {
+ if (jniRegMap.at(className).mProc(env) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static vector<string> parseCsv(const string& csvString) {
+ vector<string> result;
+ istringstream stream(csvString);
+ string segment;
+ while(getline(stream, segment, ','))
+ {
+ result.push_back(segment);
+ }
+ return result;
+}
+
+static vector<string> parseCsv(JNIEnv* env, jstring csvJString) {
+ const char* charArray = env->GetStringUTFChars(csvJString, 0);
+ string csvString(charArray);
+ vector<string> result = parseCsv(csvString);
+ env->ReleaseStringUTFChars(csvJString, charArray);
+ return result;
+}
+
+} // namespace android
+
+using namespace android;
+
+void init_android_graphics() {
+ SkGraphics::Init();
+}
+
+int register_android_graphics_classes(JNIEnv *env) {
+ JavaVM* vm = nullptr;
+ env->GetJavaVM(&vm);
+ GraphicsJNI::setJavaVM(vm);
+
+ // Configuration is stored as java System properties.
+ // Get a reference to System.getProperty
+ jclass system = FindClassOrDie(env, "java/lang/System");
+ jmethodID getPropertyMethod = GetStaticMethodIDOrDie(env, system, "getProperty",
+ "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+
+ // Get the names of classes that need to register their native methods
+ auto nativesClassesJString =
+ (jstring) env->CallStaticObjectMethod(system,
+ getPropertyMethod, env->NewStringUTF("native_classes"),
+ env->NewStringUTF(""));
+ vector<string> classesToRegister = parseCsv(env, nativesClassesJString);
+
+ if (register_jni_procs(gRegJNIMap, classesToRegister, env) < 0) {
+ return JNI_ERR;
+ }
+
+ return 0;
+}
+
+void zygote_preload_graphics() { }
diff --git a/libs/hwui/apex/TypeCast.h b/libs/hwui/apex/TypeCast.h
new file mode 100644
index 000000000000..96721d007951
--- /dev/null
+++ b/libs/hwui/apex/TypeCast.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 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_GRAPHICS_TYPECAST_H
+#define ANDROID_GRAPHICS_TYPECAST_H
+
+struct ABitmap;
+struct ACanvas;
+struct APaint;
+
+namespace android {
+
+ class Bitmap;
+ class Canvas;
+ class Paint;
+
+ class TypeCast {
+ public:
+ static inline Bitmap& toBitmapRef(const ABitmap* bitmap) {
+ return const_cast<Bitmap&>(reinterpret_cast<const Bitmap&>(*bitmap));
+ }
+
+ static inline Bitmap* toBitmap(ABitmap* bitmap) {
+ return reinterpret_cast<Bitmap*>(bitmap);
+ }
+
+ static inline ABitmap* toABitmap(Bitmap* bitmap) {
+ return reinterpret_cast<ABitmap*>(bitmap);
+ }
+
+ static inline Canvas* toCanvas(ACanvas* canvas) {
+ return reinterpret_cast<Canvas*>(canvas);
+ }
+
+ static inline ACanvas* toACanvas(Canvas* canvas) {
+ return reinterpret_cast<ACanvas *>(canvas);
+ }
+
+ static inline const Paint& toPaintRef(const APaint* paint) {
+ return reinterpret_cast<const Paint&>(*paint);
+ }
+
+ static inline const Paint* toPaint(const APaint* paint) {
+ return reinterpret_cast<const Paint*>(paint);
+ }
+
+ static inline Paint* toPaint(APaint* paint) {
+ return reinterpret_cast<Paint*>(paint);
+ }
+
+ static inline APaint* toAPaint(Paint* paint) {
+ return reinterpret_cast<APaint*>(paint);
+ }
+ };
+}; // namespace android
+
+#endif // ANDROID_GRAPHICS_TYPECAST_H
diff --git a/libs/hwui/apex/android_bitmap.cpp b/libs/hwui/apex/android_bitmap.cpp
new file mode 100644
index 000000000000..3780ba072308
--- /dev/null
+++ b/libs/hwui/apex/android_bitmap.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "Bitmap"
+#include <log/log.h>
+
+#include "android/graphics/bitmap.h"
+#include "TypeCast.h"
+#include "GraphicsJNI.h"
+
+#include <GraphicsJNI.h>
+#include <hwui/Bitmap.h>
+#include <utils/Color.h>
+
+using namespace android;
+
+ABitmap* ABitmap_acquireBitmapFromJava(JNIEnv* env, jobject bitmapObj) {
+ Bitmap* bitmap = GraphicsJNI::getNativeBitmap(env, bitmapObj);
+ if (bitmap) {
+ bitmap->ref();
+ return TypeCast::toABitmap(bitmap);
+ }
+ return nullptr;
+}
+
+void ABitmap_acquireRef(ABitmap* bitmap) {
+ SkSafeRef(TypeCast::toBitmap(bitmap));
+}
+
+void ABitmap_releaseRef(ABitmap* bitmap) {
+ SkSafeUnref(TypeCast::toBitmap(bitmap));
+}
+
+static AndroidBitmapFormat getFormat(const SkImageInfo& info) {
+ switch (info.colorType()) {
+ case kN32_SkColorType:
+ return ANDROID_BITMAP_FORMAT_RGBA_8888;
+ case kRGB_565_SkColorType:
+ return ANDROID_BITMAP_FORMAT_RGB_565;
+ case kARGB_4444_SkColorType:
+ return ANDROID_BITMAP_FORMAT_RGBA_4444;
+ case kAlpha_8_SkColorType:
+ return ANDROID_BITMAP_FORMAT_A_8;
+ case kRGBA_F16_SkColorType:
+ return ANDROID_BITMAP_FORMAT_RGBA_F16;
+ default:
+ return ANDROID_BITMAP_FORMAT_NONE;
+ }
+}
+
+static SkColorType getColorType(AndroidBitmapFormat format) {
+ switch (format) {
+ case ANDROID_BITMAP_FORMAT_RGBA_8888:
+ return kN32_SkColorType;
+ case ANDROID_BITMAP_FORMAT_RGB_565:
+ return kRGB_565_SkColorType;
+ case ANDROID_BITMAP_FORMAT_RGBA_4444:
+ return kARGB_4444_SkColorType;
+ case ANDROID_BITMAP_FORMAT_A_8:
+ return kAlpha_8_SkColorType;
+ case ANDROID_BITMAP_FORMAT_RGBA_F16:
+ return kRGBA_F16_SkColorType;
+ default:
+ return kUnknown_SkColorType;
+ }
+}
+
+static uint32_t getAlphaFlags(const SkImageInfo& info) {
+ switch (info.alphaType()) {
+ case kUnknown_SkAlphaType:
+ LOG_ALWAYS_FATAL("Bitmap has no alpha type");
+ break;
+ case kOpaque_SkAlphaType:
+ return ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE;
+ case kPremul_SkAlphaType:
+ return ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
+ case kUnpremul_SkAlphaType:
+ return ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL;
+ }
+}
+
+static uint32_t getInfoFlags(const SkImageInfo& info, bool isHardware) {
+ uint32_t flags = getAlphaFlags(info);
+ if (isHardware) {
+ flags |= ANDROID_BITMAP_FLAGS_IS_HARDWARE;
+ }
+ return flags;
+}
+
+ABitmap* ABitmap_copy(ABitmap* srcBitmapHandle, AndroidBitmapFormat dstFormat) {
+ SkColorType dstColorType = getColorType(dstFormat);
+ if (srcBitmapHandle && dstColorType != kUnknown_SkColorType) {
+ SkBitmap srcBitmap;
+ TypeCast::toBitmap(srcBitmapHandle)->getSkBitmap(&srcBitmap);
+
+ sk_sp<Bitmap> dstBitmap =
+ Bitmap::allocateHeapBitmap(srcBitmap.info().makeColorType(dstColorType));
+ if (dstBitmap && srcBitmap.readPixels(dstBitmap->info(), dstBitmap->pixels(),
+ dstBitmap->rowBytes(), 0, 0)) {
+ return TypeCast::toABitmap(dstBitmap.release());
+ }
+ }
+ return nullptr;
+}
+
+static AndroidBitmapInfo getInfo(const SkImageInfo& imageInfo, uint32_t rowBytes, bool isHardware) {
+ AndroidBitmapInfo info;
+ info.width = imageInfo.width();
+ info.height = imageInfo.height();
+ info.stride = rowBytes;
+ info.format = getFormat(imageInfo);
+ info.flags = getInfoFlags(imageInfo, isHardware);
+ return info;
+}
+
+AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmapHandle) {
+ Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
+ return getInfo(bitmap->info(), bitmap->rowBytes(), bitmap->isHardware());
+}
+
+ADataSpace ABitmap_getDataSpace(ABitmap* bitmapHandle) {
+ Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
+ const SkImageInfo& info = bitmap->info();
+ return (ADataSpace)uirenderer::ColorSpaceToADataSpace(info.colorSpace(), info.colorType());
+}
+
+AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj) {
+ uint32_t rowBytes = 0;
+ bool isHardware = false;
+ SkImageInfo imageInfo = GraphicsJNI::getBitmapInfo(env, bitmapObj, &rowBytes, &isHardware);
+ return getInfo(imageInfo, rowBytes, isHardware);
+}
+
+void* ABitmap_getPixels(ABitmap* bitmapHandle) {
+ Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
+ if (bitmap->isHardware()) {
+ return nullptr;
+ }
+ return bitmap->pixels();
+}
+
+AndroidBitmapFormat ABitmapConfig_getFormatFromConfig(JNIEnv* env, jobject bitmapConfigObj) {
+ return GraphicsJNI::getFormatFromConfig(env, bitmapConfigObj);
+}
+
+jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format) {
+ return GraphicsJNI::getConfigFromFormat(env, format);
+}
+
+void ABitmap_notifyPixelsChanged(ABitmap* bitmapHandle) {
+ Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
+ if (!bitmap->isImmutable()) {
+ bitmap->notifyPixelsChanged();
+ }
+}
+
+namespace {
+SkAlphaType getAlphaType(const AndroidBitmapInfo* info) {
+ switch (info->flags & ANDROID_BITMAP_FLAGS_ALPHA_MASK) {
+ case ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE:
+ return kOpaque_SkAlphaType;
+ case ANDROID_BITMAP_FLAGS_ALPHA_PREMUL:
+ return kPremul_SkAlphaType;
+ case ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL:
+ return kUnpremul_SkAlphaType;
+ default:
+ return kUnknown_SkAlphaType;
+ }
+}
+
+class CompressWriter : public SkWStream {
+public:
+ CompressWriter(void* userContext, AndroidBitmap_CompressWriteFunc fn)
+ : mUserContext(userContext), mFn(fn), mBytesWritten(0) {}
+
+ bool write(const void* buffer, size_t size) override {
+ if (mFn(mUserContext, buffer, size)) {
+ mBytesWritten += size;
+ return true;
+ }
+ return false;
+ }
+
+ size_t bytesWritten() const override { return mBytesWritten; }
+
+private:
+ void* mUserContext;
+ AndroidBitmap_CompressWriteFunc mFn;
+ size_t mBytesWritten;
+};
+
+} // anonymous namespace
+
+int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const void* pixels,
+ AndroidBitmapCompressFormat inFormat, int32_t quality, void* userContext,
+ AndroidBitmap_CompressWriteFunc fn) {
+ Bitmap::JavaCompressFormat format;
+ switch (inFormat) {
+ case ANDROID_BITMAP_COMPRESS_FORMAT_JPEG:
+ format = Bitmap::JavaCompressFormat::Jpeg;
+ break;
+ case ANDROID_BITMAP_COMPRESS_FORMAT_PNG:
+ format = Bitmap::JavaCompressFormat::Png;
+ break;
+ case ANDROID_BITMAP_COMPRESS_FORMAT_WEBP_LOSSY:
+ format = Bitmap::JavaCompressFormat::WebpLossy;
+ break;
+ case ANDROID_BITMAP_COMPRESS_FORMAT_WEBP_LOSSLESS:
+ format = Bitmap::JavaCompressFormat::WebpLossless;
+ break;
+ default:
+ // kWEBP_JavaEncodeFormat is a valid parameter for Bitmap::compress,
+ // for the deprecated Bitmap.CompressFormat.WEBP, but it should not
+ // be provided via the NDK. Other integers are likewise invalid.
+ return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+ }
+
+ SkColorType colorType;
+ switch (info->format) {
+ case ANDROID_BITMAP_FORMAT_RGBA_8888:
+ colorType = kN32_SkColorType;
+ break;
+ case ANDROID_BITMAP_FORMAT_RGB_565:
+ colorType = kRGB_565_SkColorType;
+ break;
+ case ANDROID_BITMAP_FORMAT_A_8:
+ // FIXME b/146637821: Should this encode as grayscale? We should
+ // make the same decision as for encoding an android.graphics.Bitmap.
+ // Note that encoding kAlpha_8 as WebP or JPEG will fail. Encoding
+ // it to PNG encodes as GRAY+ALPHA with a secret handshake that we
+ // only care about the alpha. I'm not sure whether Android decoding
+ // APIs respect that handshake.
+ colorType = kAlpha_8_SkColorType;
+ break;
+ case ANDROID_BITMAP_FORMAT_RGBA_F16:
+ colorType = kRGBA_F16_SkColorType;
+ break;
+ default:
+ return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+ }
+
+ auto alphaType = getAlphaType(info);
+ if (alphaType == kUnknown_SkAlphaType) {
+ return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+ }
+
+ sk_sp<SkColorSpace> cs;
+ if (info->format == ANDROID_BITMAP_FORMAT_A_8) {
+ // FIXME: A Java Bitmap with ALPHA_8 never has a ColorSpace. So should
+ // we force that here (as I'm doing now) or should we treat anything
+ // besides ADATASPACE_UNKNOWN as an error?
+ cs = nullptr;
+ } else {
+ cs = uirenderer::DataSpaceToColorSpace((android_dataspace) dataSpace);
+ // DataSpaceToColorSpace treats UNKNOWN as SRGB, but compress forces the
+ // client to specify SRGB if that is what they want.
+ if (!cs || dataSpace == ADATASPACE_UNKNOWN) {
+ return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+ }
+ }
+
+ {
+ size_t size;
+ if (!Bitmap::computeAllocationSize(info->stride, info->height, &size)) {
+ return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+ }
+ }
+
+ auto imageInfo =
+ SkImageInfo::Make(info->width, info->height, colorType, alphaType, std::move(cs));
+ SkBitmap bitmap;
+ // We are not going to modify the pixels, but installPixels expects them to
+ // not be const, since for all it knows we might want to draw to the SkBitmap.
+ if (!bitmap.installPixels(imageInfo, const_cast<void*>(pixels), info->stride)) {
+ return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+ }
+
+ CompressWriter stream(userContext, fn);
+ return Bitmap::compress(bitmap, format, quality, &stream) ? ANDROID_BITMAP_RESULT_SUCCESS
+ : ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
+}
+
+AHardwareBuffer* ABitmap_getHardwareBuffer(ABitmap* bitmapHandle) {
+ Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
+ AHardwareBuffer* buffer = bitmap->hardwareBuffer();
+ if (buffer) {
+ AHardwareBuffer_acquire(buffer);
+ }
+ return buffer;
+}
diff --git a/libs/hwui/apex/android_canvas.cpp b/libs/hwui/apex/android_canvas.cpp
new file mode 100644
index 000000000000..2a939efed9bb
--- /dev/null
+++ b/libs/hwui/apex/android_canvas.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2019 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 "android/graphics/canvas.h"
+
+#include "TypeCast.h"
+#include "GraphicsJNI.h"
+
+#include <hwui/Canvas.h>
+#include <utils/Color.h>
+
+#include <SkBitmap.h>
+#include <SkSurface.h>
+
+using namespace android;
+
+/*
+ * Converts a buffer and dataspace into an SkBitmap only if the resulting bitmap can be treated as a
+ * rendering destination for a Canvas. If the buffer is null or the format is one that we cannot
+ * render into with a Canvas then false is returned and the outBitmap param is unmodified.
+ */
+static bool convert(const ANativeWindow_Buffer* buffer,
+ int32_t /*android_dataspace_t*/ dataspace,
+ SkBitmap* outBitmap) {
+ if (buffer == nullptr) {
+ return false;
+ }
+
+ sk_sp<SkColorSpace> cs(uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace));
+ SkImageInfo imageInfo = uirenderer::ANativeWindowToImageInfo(*buffer, cs);
+ size_t rowBytes = buffer->stride * imageInfo.bytesPerPixel();
+
+ // If SkSurface::MakeRasterDirect fails then we should as well as we will not be able to
+ // draw into the canvas.
+ sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(imageInfo, buffer->bits, rowBytes);
+ if (surface.get() != nullptr) {
+ if (outBitmap) {
+ outBitmap->setInfo(imageInfo, rowBytes);
+ outBitmap->setPixels(buffer->bits);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool ACanvas_isSupportedPixelFormat(int32_t bufferFormat) {
+ char pixels[8];
+ ANativeWindow_Buffer buffer { 1, 1, 1, bufferFormat, pixels, {0} };
+ return convert(&buffer, HAL_DATASPACE_UNKNOWN, nullptr);
+}
+
+ACanvas* ACanvas_getNativeHandleFromJava(JNIEnv* env, jobject canvasObj) {
+ return TypeCast::toACanvas(GraphicsJNI::getNativeCanvas(env, canvasObj));
+}
+
+ACanvas* ACanvas_createCanvas(const ANativeWindow_Buffer* buffer,
+ int32_t /*android_dataspace_t*/ dataspace) {
+ SkBitmap bitmap;
+ bool isValidBuffer = convert(buffer, dataspace, &bitmap);
+ return isValidBuffer ? TypeCast::toACanvas(Canvas::create_canvas(bitmap)) : nullptr;
+}
+
+void ACanvas_destroyCanvas(ACanvas* canvas) {
+ delete TypeCast::toCanvas(canvas);
+}
+
+bool ACanvas_setBuffer(ACanvas* canvas, const ANativeWindow_Buffer* buffer,
+ int32_t /*android_dataspace_t*/ dataspace) {
+ SkBitmap bitmap;
+ bool isValidBuffer = (buffer == nullptr) ? false : convert(buffer, dataspace, &bitmap);
+ TypeCast::toCanvas(canvas)->setBitmap(bitmap);
+ return isValidBuffer;
+}
+
+void ACanvas_clipRect(ACanvas* canvas, const ARect* clipRect, bool /*doAA*/) {
+ //TODO update Canvas to take antialias param
+ TypeCast::toCanvas(canvas)->clipRect(clipRect->left, clipRect->top, clipRect->right,
+ clipRect->bottom, SkClipOp::kIntersect);
+}
+
+void ACanvas_clipOutRect(ACanvas* canvas, const ARect* clipRect, bool /*doAA*/) {
+ //TODO update Canvas to take antialias param
+ TypeCast::toCanvas(canvas)->clipRect(clipRect->left, clipRect->top, clipRect->right,
+ clipRect->bottom, SkClipOp::kDifference);
+}
+
+void ACanvas_drawRect(ACanvas* canvas, const ARect* rect, const APaint* paint) {
+ TypeCast::toCanvas(canvas)->drawRect(rect->left, rect->top, rect->right, rect->bottom,
+ TypeCast::toPaintRef(paint));
+}
+
+void ACanvas_drawBitmap(ACanvas* canvas, const ABitmap* bitmap, float left, float top,
+ const APaint* paint) {
+ TypeCast::toCanvas(canvas)->drawBitmap(TypeCast::toBitmapRef(bitmap), left, top,
+ TypeCast::toPaint(paint));
+}
diff --git a/libs/hwui/apex/android_matrix.cpp b/libs/hwui/apex/android_matrix.cpp
new file mode 100644
index 000000000000..693b22b62663
--- /dev/null
+++ b/libs/hwui/apex/android_matrix.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 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 "android/graphics/matrix.h"
+#include "android_graphics_Matrix.h"
+
+bool AMatrix_getContents(JNIEnv* env, jobject matrixObj, float values[9]) {
+ static_assert(SkMatrix::kMScaleX == 0, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMSkewX == 1, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMTransX == 2, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMSkewY == 3, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMScaleY == 4, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMTransY == 5, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMPersp0 == 6, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMPersp1 == 7, "SkMatrix unexpected index");
+ static_assert(SkMatrix::kMPersp2 == 8, "SkMatrix unexpected index");
+
+ SkMatrix* m = android::android_graphics_Matrix_getSkMatrix(env, matrixObj);
+ if (m != nullptr) {
+ m->get9(values);
+ return true;
+ }
+ return false;
+}
diff --git a/libs/hwui/apex/android_paint.cpp b/libs/hwui/apex/android_paint.cpp
new file mode 100644
index 000000000000..70bd085343ce
--- /dev/null
+++ b/libs/hwui/apex/android_paint.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 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 "android/graphics/paint.h"
+
+#include "TypeCast.h"
+
+#include <hwui/Paint.h>
+
+using namespace android;
+
+
+APaint* APaint_createPaint() {
+ return TypeCast::toAPaint(new Paint());
+}
+
+void APaint_destroyPaint(APaint* paint) {
+ delete TypeCast::toPaint(paint);
+}
+
+static SkBlendMode convertBlendMode(ABlendMode blendMode) {
+ switch (blendMode) {
+ case ABLEND_MODE_CLEAR:
+ return SkBlendMode::kClear;
+ case ABLEND_MODE_SRC_OVER:
+ return SkBlendMode::kSrcOver;
+ case ABLEND_MODE_SRC:
+ return SkBlendMode::kSrc;
+ }
+}
+
+void APaint_setBlendMode(APaint* paint, ABlendMode blendMode) {
+ TypeCast::toPaint(paint)->setBlendMode(convertBlendMode(blendMode));
+}
diff --git a/libs/hwui/apex/android_region.cpp b/libs/hwui/apex/android_region.cpp
new file mode 100644
index 000000000000..2030e7e69861
--- /dev/null
+++ b/libs/hwui/apex/android_region.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 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 "android/graphics/region.h"
+
+#include "GraphicsJNI.h"
+
+#include <SkRegion.h>
+
+static inline SkRegion::Iterator* ARegionIter_to_SkRegionIter(ARegionIterator* iterator) {
+ return reinterpret_cast<SkRegion::Iterator*>(iterator);
+}
+
+static inline ARegionIterator* SkRegionIter_to_ARegionIter(SkRegion::Iterator* iterator) {
+ return reinterpret_cast<ARegionIterator*>(iterator);
+}
+
+ARegionIterator* ARegionIterator_acquireIterator(JNIEnv* env, jobject regionObj) {
+ SkRegion* region = GraphicsJNI::getNativeRegion(env, regionObj);
+ return (!region) ? nullptr : SkRegionIter_to_ARegionIter(new SkRegion::Iterator(*region));
+}
+
+void ARegionIterator_releaseIterator(ARegionIterator* iterator) {
+ delete ARegionIter_to_SkRegionIter(iterator);
+}
+
+bool ARegionIterator_isComplex(ARegionIterator* iterator) {
+ return ARegionIter_to_SkRegionIter(iterator)->rgn()->isComplex();
+}
+
+bool ARegionIterator_isDone(ARegionIterator* iterator) {
+ return ARegionIter_to_SkRegionIter(iterator)->done();
+}
+
+void ARegionIterator_next(ARegionIterator* iterator) {
+ ARegionIter_to_SkRegionIter(iterator)->next();
+}
+
+ARect ARegionIterator_getRect(ARegionIterator* iterator) {
+ const SkIRect& rect = ARegionIter_to_SkRegionIter(iterator)->rect();
+ return { rect.fLeft, rect.fTop, rect.fRight, rect.fBottom };
+}
+
+ARect ARegionIterator_getTotalBounds(ARegionIterator* iterator) {
+ const SkIRect& bounds = ARegionIter_to_SkRegionIter(iterator)->rgn()->getBounds();
+ return { bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom };
+}
diff --git a/libs/hwui/apex/include/android/graphics/bitmap.h b/libs/hwui/apex/include/android/graphics/bitmap.h
new file mode 100644
index 000000000000..8c4b439d2a2b
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/bitmap.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2019 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_GRAPHICS_BITMAP_H
+#define ANDROID_GRAPHICS_BITMAP_H
+
+#include <android/bitmap.h>
+#include <android/data_space.h>
+#include <cutils/compiler.h>
+#include <jni.h>
+#include <sys/cdefs.h>
+
+struct AHardwareBuffer;
+
+__BEGIN_DECLS
+
+/**
+ * Opaque handle for a native graphics bitmap.
+ */
+typedef struct ABitmap ABitmap;
+
+/**
+ * Retrieve bitmapInfo for the provided java bitmap even if it has been recycled. In the case of a
+ * recycled bitmap the values contained in the bitmap before it was recycled are returned.
+ *
+ * NOTE: This API does not need to remain as an APEX API if/when we pull libjnigraphics into the
+ * UI module.
+ */
+ANDROID_API AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj);
+
+/**
+ *
+ * @return ptr to an opaque handle to the native bitmap or null if the java bitmap has been recycled
+ * or does not exist.
+ */
+ANDROID_API ABitmap* ABitmap_acquireBitmapFromJava(JNIEnv* env, jobject bitmapObj);
+
+ANDROID_API ABitmap* ABitmap_copy(ABitmap* srcBitmap, AndroidBitmapFormat dstFormat);
+
+ANDROID_API void ABitmap_acquireRef(ABitmap* bitmap);
+ANDROID_API void ABitmap_releaseRef(ABitmap* bitmap);
+
+ANDROID_API AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmap);
+ANDROID_API ADataSpace ABitmap_getDataSpace(ABitmap* bitmap);
+
+ANDROID_API void* ABitmap_getPixels(ABitmap* bitmap);
+ANDROID_API void ABitmap_notifyPixelsChanged(ABitmap* bitmap);
+
+ANDROID_API AndroidBitmapFormat ABitmapConfig_getFormatFromConfig(JNIEnv* env, jobject bitmapConfigObj);
+ANDROID_API jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);
+
+// NDK access
+ANDROID_API int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const void* pixels,
+ AndroidBitmapCompressFormat format, int32_t quality, void* userContext,
+ AndroidBitmap_CompressWriteFunc);
+/**
+ * Retrieve the native object associated with a HARDWARE Bitmap.
+ *
+ * Client must not modify it while a Bitmap is wrapping it.
+ *
+ * @param bitmap Handle to an android.graphics.Bitmap.
+ * @return on success, a pointer to the
+ * AHardwareBuffer associated with bitmap. This acquires
+ * a reference on the buffer, and the client must call
+ * AHardwareBuffer_release when finished with it.
+ */
+ANDROID_API AHardwareBuffer* ABitmap_getHardwareBuffer(ABitmap* bitmap);
+
+__END_DECLS
+
+#ifdef __cplusplus
+namespace android {
+namespace graphics {
+ class Bitmap {
+ public:
+ Bitmap() : mBitmap(nullptr) {}
+ Bitmap(JNIEnv* env, jobject bitmapObj) :
+ mBitmap(ABitmap_acquireBitmapFromJava(env, bitmapObj)) {}
+ Bitmap(const Bitmap& src) : mBitmap(src.mBitmap) { ABitmap_acquireRef(src.mBitmap); }
+ ~Bitmap() { ABitmap_releaseRef(mBitmap); }
+
+ // copy operator
+ Bitmap& operator=(const Bitmap& other) {
+ if (&other != this) {
+ ABitmap_releaseRef(mBitmap);
+ mBitmap = other.mBitmap;
+ ABitmap_acquireRef(mBitmap);
+ }
+ return *this;
+ }
+
+ // move operator
+ Bitmap& operator=(Bitmap&& other) {
+ if (&other != this) {
+ ABitmap_releaseRef(mBitmap);
+ mBitmap = other.mBitmap;
+ other.mBitmap = nullptr;
+ }
+ return *this;
+ }
+
+ Bitmap copy(AndroidBitmapFormat dstFormat) const {
+ return Bitmap(ABitmap_copy(mBitmap, dstFormat));
+ }
+
+ bool isValid() const { return mBitmap != nullptr; }
+ bool isEmpty() const {
+ AndroidBitmapInfo info = getInfo();
+ return info.width <= 0 || info.height <= 0;
+ }
+ void reset() {
+ ABitmap_releaseRef(mBitmap);
+ mBitmap = nullptr;
+ }
+
+ ABitmap* get() const { return mBitmap; }
+
+ AndroidBitmapInfo getInfo() const { return ABitmap_getInfo(mBitmap); }
+ ADataSpace getDataSpace() const { return ABitmap_getDataSpace(mBitmap); }
+ void* getPixels() const { return ABitmap_getPixels(mBitmap); }
+ void notifyPixelsChanged() const { ABitmap_notifyPixelsChanged(mBitmap); }
+ AHardwareBuffer* getHardwareBuffer() const { return ABitmap_getHardwareBuffer(mBitmap); }
+
+ private:
+ // takes ownership of the provided ABitmap
+ Bitmap(ABitmap* bitmap) : mBitmap(bitmap) {}
+
+ ABitmap* mBitmap;
+ };
+}; // namespace graphics
+}; // namespace android
+#endif // __cplusplus
+
+#endif // ANDROID_GRAPHICS_BITMAP_H
diff --git a/libs/hwui/apex/include/android/graphics/canvas.h b/libs/hwui/apex/include/android/graphics/canvas.h
new file mode 100644
index 000000000000..a0cecc04a7e5
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/canvas.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 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_GRAPHICS_CANVAS_H
+#define ANDROID_GRAPHICS_CANVAS_H
+
+#include <android/graphics/bitmap.h>
+#include <android/graphics/paint.h>
+#include <android/native_window.h>
+#include <android/rect.h>
+#include <cutils/compiler.h>
+#include <jni.h>
+
+__BEGIN_DECLS
+
+/**
+ * Opaque handle for a native graphics canvas.
+ */
+typedef struct ACanvas ACanvas;
+
+// One of AHardwareBuffer_Format.
+ANDROID_API bool ACanvas_isSupportedPixelFormat(int32_t bufferFormat);
+
+/**
+ * Returns a native handle to a Java android.graphics.Canvas
+ *
+ * @return ACanvas* that is only valid for the life of the jobject.
+ */
+ANDROID_API ACanvas* ACanvas_getNativeHandleFromJava(JNIEnv* env, jobject canvas);
+
+/**
+ * Creates a canvas that wraps the buffer
+ *
+ * @param buffer is a required param. If no buffer is provided a nullptr will be returned.
+ */
+ANDROID_API ACanvas* ACanvas_createCanvas(const ANativeWindow_Buffer* buffer,
+ int32_t /*android_dataspace_t*/ dataspace);
+
+ANDROID_API void ACanvas_destroyCanvas(ACanvas* canvas);
+
+/**
+ * Updates the canvas to render into the pixels in the provided buffer
+ *
+ * @param buffer The buffer that will provide the backing store for this canvas. The buffer must
+ * remain valid until the this method is called again with either another active
+ * buffer or nullptr. If nullptr is given the canvas will release the previous buffer
+ * and set an empty backing store.
+ * @return A boolean value indicating whether or not the buffer was successfully set. If false the
+ * method will behave as if nullptr were passed as the input buffer and the previous buffer
+ * will still be released.
+ */
+ANDROID_API bool ACanvas_setBuffer(ACanvas* canvas, const ANativeWindow_Buffer* buffer,
+ int32_t /*android_dataspace_t*/ dataspace);
+
+/**
+ * Clips operations on the canvas to the intersection of the current clip and the provided clipRect.
+ *
+ * @param clipRect required
+ */
+ANDROID_API void ACanvas_clipRect(ACanvas* canvas, const ARect* clipRect, bool doAntiAlias = false);
+
+/**
+ * Clips operations on the canvas to the difference of the current clip and the provided clipRect.
+ *
+ * @param clipRect required
+ */
+ANDROID_API void ACanvas_clipOutRect(ACanvas* canvas, const ARect* clipRect, bool doAntiAlias = false);
+
+/**
+ *
+ * @param rect required
+ * @param paint required
+ */
+ANDROID_API void ACanvas_drawRect(ACanvas* canvas, const ARect* rect, const APaint* paint);
+
+/**
+ *
+ * @param bitmap required
+ * @param left
+ * @param top
+ * @param paint
+ */
+ANDROID_API void ACanvas_drawBitmap(ACanvas* canvas, const ABitmap* bitmap, float left, float top,
+ const APaint* paint);
+
+__END_DECLS
+
+#ifdef __cplusplus
+namespace android {
+namespace graphics {
+ class Canvas {
+ public:
+ Canvas(JNIEnv* env, jobject canvasObj) :
+ mCanvas(ACanvas_getNativeHandleFromJava(env, canvasObj)),
+ mOwnedPtr(false) {}
+ Canvas(const ANativeWindow_Buffer& buffer, int32_t /*android_dataspace_t*/ dataspace) :
+ mCanvas(ACanvas_createCanvas(&buffer, dataspace)),
+ mOwnedPtr(true) {}
+ ~Canvas() {
+ if (mOwnedPtr) {
+ ACanvas_destroyCanvas(mCanvas);
+ }
+ }
+
+ bool setBuffer(const ANativeWindow_Buffer* buffer,
+ int32_t /*android_dataspace_t*/ dataspace) {
+ return ACanvas_setBuffer(mCanvas, buffer, dataspace);
+ }
+
+ void clipRect(const ARect& clipRect, bool doAntiAlias = false) {
+ ACanvas_clipRect(mCanvas, &clipRect, doAntiAlias);
+ }
+
+ void drawRect(const ARect& rect, const Paint& paint) {
+ ACanvas_drawRect(mCanvas, &rect, &paint.get());
+ }
+ void drawBitmap(const Bitmap& bitmap, float left, float top, const Paint* paint) {
+ const APaint* aPaint = (paint) ? &paint->get() : nullptr;
+ ACanvas_drawBitmap(mCanvas, bitmap.get(), left, top, aPaint);
+ }
+
+ private:
+ ACanvas* mCanvas;
+ const bool mOwnedPtr;
+ };
+}; // namespace graphics
+}; // namespace android
+#endif // __cplusplus
+
+#endif // ANDROID_GRAPHICS_CANVAS_H \ No newline at end of file
diff --git a/libs/hwui/apex/include/android/graphics/jni_runtime.h b/libs/hwui/apex/include/android/graphics/jni_runtime.h
new file mode 100644
index 000000000000..487383ed50d5
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/jni_runtime.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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_GRAPHICS_JNI_RUNTIME_H
+#define ANDROID_GRAPHICS_JNI_RUNTIME_H
+
+#include <cutils/compiler.h>
+#include <jni.h>
+
+__BEGIN_DECLS
+
+ANDROID_API void init_android_graphics();
+
+ANDROID_API int register_android_graphics_classes(JNIEnv* env);
+
+ANDROID_API int register_android_graphics_GraphicsStatsService(JNIEnv* env);
+
+ANDROID_API void zygote_preload_graphics();
+
+__END_DECLS
+
+
+#endif // ANDROID_GRAPHICS_JNI_RUNTIME_H \ No newline at end of file
diff --git a/libs/hwui/apex/include/android/graphics/matrix.h b/libs/hwui/apex/include/android/graphics/matrix.h
new file mode 100644
index 000000000000..987ad13f7635
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/matrix.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 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_GRAPHICS_MATRIX_H
+#define ANDROID_GRAPHICS_MATRIX_H
+
+#include <jni.h>
+#include <cutils/compiler.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * Returns an array of floats that represents the 3x3 matrix of the java object.
+ * @param values The 9 values of the 3x3 matrix in the following order.
+ * values[0] = scaleX values[1] = skewX values[2] = transX
+ * values[3] = skewY values[4] = scaleY values[5] = transY
+ * values[6] = persp0 values[7] = persp1 values[8] = persp2
+ * @return true if the values param was populated and false otherwise.
+
+ */
+ANDROID_API bool AMatrix_getContents(JNIEnv* env, jobject matrixObj, float values[9]);
+
+__END_DECLS
+
+#endif // ANDROID_GRAPHICS_MATRIX_H
diff --git a/libs/hwui/apex/include/android/graphics/paint.h b/libs/hwui/apex/include/android/graphics/paint.h
new file mode 100644
index 000000000000..058db8d37619
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/paint.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 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_GRAPHICS_PAINT_H
+#define ANDROID_GRAPHICS_PAINT_H
+
+#include <cutils/compiler.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * Opaque handle for a native graphics canvas.
+ */
+typedef struct APaint APaint;
+
+/** Bitmap pixel format. */
+enum ABlendMode {
+ /** replaces destination with zero: fully transparent */
+ ABLEND_MODE_CLEAR = 0,
+ /** source over destination */
+ ABLEND_MODE_SRC_OVER = 1,
+ /** replaces destination **/
+ ABLEND_MODE_SRC = 2,
+};
+
+ANDROID_API APaint* APaint_createPaint();
+
+ANDROID_API void APaint_destroyPaint(APaint* paint);
+
+ANDROID_API void APaint_setBlendMode(APaint* paint, ABlendMode blendMode);
+
+__END_DECLS
+
+#ifdef __cplusplus
+namespace android {
+namespace graphics {
+ class Paint {
+ public:
+ Paint() : mPaint(APaint_createPaint()) {}
+ ~Paint() { APaint_destroyPaint(mPaint); }
+
+ void setBlendMode(ABlendMode blendMode) { APaint_setBlendMode(mPaint, blendMode); }
+
+ const APaint& get() const { return *mPaint; }
+
+ private:
+ APaint* mPaint;
+ };
+}; // namespace graphics
+}; // namespace android
+#endif // __cplusplus
+
+
+#endif // ANDROID_GRAPHICS_PAINT_H \ No newline at end of file
diff --git a/libs/hwui/apex/include/android/graphics/region.h b/libs/hwui/apex/include/android/graphics/region.h
new file mode 100644
index 000000000000..0756d6dd63f6
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/region.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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_GRAPHICS_REGION_H
+#define ANDROID_GRAPHICS_REGION_H
+
+#include <cutils/compiler.h>
+#include <android/rect.h>
+#include <sys/cdefs.h>
+#include <jni.h>
+
+__BEGIN_DECLS
+
+/**
+* Opaque handle for a native graphics region iterator.
+*/
+typedef struct ARegionIterator ARegionIterator;
+
+/**
+ * Returns a iterator for a Java android.graphics.Region
+ *
+ * @param env
+ * @param region
+ * @return ARegionIterator that must be closed and must not live longer than the life
+ * of the jobject. It returns nullptr if the region is not a valid object.
+ */
+ANDROID_API ARegionIterator* ARegionIterator_acquireIterator(JNIEnv* env, jobject region);
+
+ANDROID_API void ARegionIterator_releaseIterator(ARegionIterator* iterator);
+
+ANDROID_API bool ARegionIterator_isComplex(ARegionIterator* iterator);
+
+ANDROID_API bool ARegionIterator_isDone(ARegionIterator* iterator);
+
+ANDROID_API void ARegionIterator_next(ARegionIterator* iterator);
+
+ANDROID_API ARect ARegionIterator_getRect(ARegionIterator* iterator);
+
+ANDROID_API ARect ARegionIterator_getTotalBounds(ARegionIterator* iterator);
+
+__END_DECLS
+
+#ifdef __cplusplus
+namespace android {
+namespace graphics {
+ class RegionIterator {
+ public:
+ RegionIterator(JNIEnv* env, jobject region)
+ : mIterator(ARegionIterator_acquireIterator(env, region)) {}
+ ~RegionIterator() { ARegionIterator_releaseIterator(mIterator); }
+
+ bool isValid() const { return mIterator != nullptr; }
+ bool isComplex() { return ARegionIterator_isComplex(mIterator); }
+ bool isDone() { return ARegionIterator_isDone(mIterator); }
+ void next() { ARegionIterator_next(mIterator); }
+ ARect getRect() { return ARegionIterator_getRect(mIterator); }
+ ARect getTotalBounds() const { return ARegionIterator_getTotalBounds(mIterator); }
+ private:
+ ARegionIterator* mIterator;
+ };
+}; // namespace graphics
+}; // namespace android
+
+#endif // __cplusplus
+#endif // ANDROID_GRAPHICS_REGION_H \ No newline at end of file
diff --git a/libs/hwui/apex/include/android/graphics/renderthread.h b/libs/hwui/apex/include/android/graphics/renderthread.h
new file mode 100644
index 000000000000..50280a6dd1fb
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/renderthread.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 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_GRAPHICS_RENDERTHREAD_H
+#define ANDROID_GRAPHICS_RENDERTHREAD_H
+
+#include <cutils/compiler.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * Dumps a textual representation of the graphics stats for this process.
+ * @param fd The file descriptor that the available graphics stats will be appended to. The
+ * function requires a valid fd, but does not persist or assume ownership of the fd
+ * outside the scope of this function.
+ */
+ANDROID_API void ARenderThread_dumpGraphicsMemory(int fd);
+
+__END_DECLS
+
+#endif // ANDROID_GRAPHICS_RENDERTHREAD_H
diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp
new file mode 100644
index 000000000000..a114e2f42157
--- /dev/null
+++ b/libs/hwui/apex/jni_runtime.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2019 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 "android/graphics/jni_runtime.h"
+
+#include <android/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <sys/cdefs.h>
+
+#include <EGL/egl.h>
+#include <GraphicsJNI.h>
+#include <Properties.h>
+#include <SkGraphics.h>
+
+#undef LOG_TAG
+#define LOG_TAG "AndroidGraphicsJNI"
+
+extern int register_android_graphics_Bitmap(JNIEnv*);
+extern int register_android_graphics_BitmapFactory(JNIEnv*);
+extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*);
+extern int register_android_graphics_ByteBufferStreamAdaptor(JNIEnv* env);
+extern int register_android_graphics_Camera(JNIEnv* env);
+extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env);
+extern int register_android_graphics_Graphics(JNIEnv* env);
+extern int register_android_graphics_ImageDecoder(JNIEnv*);
+extern int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv*);
+extern int register_android_graphics_Interpolator(JNIEnv* env);
+extern int register_android_graphics_MaskFilter(JNIEnv* env);
+extern int register_android_graphics_Movie(JNIEnv* env);
+extern int register_android_graphics_NinePatch(JNIEnv*);
+extern int register_android_graphics_PathEffect(JNIEnv* env);
+extern int register_android_graphics_Shader(JNIEnv* env);
+extern int register_android_graphics_Typeface(JNIEnv* env);
+extern int register_android_graphics_YuvImage(JNIEnv* env);
+
+namespace android {
+
+extern int register_android_graphics_Canvas(JNIEnv* env);
+extern int register_android_graphics_CanvasProperty(JNIEnv* env);
+extern int register_android_graphics_ColorFilter(JNIEnv* env);
+extern int register_android_graphics_ColorSpace(JNIEnv* env);
+extern int register_android_graphics_DrawFilter(JNIEnv* env);
+extern int register_android_graphics_FontFamily(JNIEnv* env);
+extern int register_android_graphics_HardwareRendererObserver(JNIEnv* env);
+extern int register_android_graphics_Matrix(JNIEnv* env);
+extern int register_android_graphics_Paint(JNIEnv* env);
+extern int register_android_graphics_Path(JNIEnv* env);
+extern int register_android_graphics_PathMeasure(JNIEnv* env);
+extern int register_android_graphics_Picture(JNIEnv*);
+extern int register_android_graphics_Region(JNIEnv* env);
+extern int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env);
+extern int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env);
+extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
+extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
+extern int register_android_graphics_fonts_Font(JNIEnv* env);
+extern int register_android_graphics_fonts_FontFamily(JNIEnv* env);
+extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
+extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
+extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
+extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
+extern int register_android_graphics_text_LineBreaker(JNIEnv *env);
+
+extern int register_android_util_PathParser(JNIEnv* env);
+extern int register_android_view_DisplayListCanvas(JNIEnv* env);
+extern int register_android_view_RenderNode(JNIEnv* env);
+extern int register_android_view_TextureLayer(JNIEnv* env);
+extern int register_android_view_ThreadedRenderer(JNIEnv* env);
+
+#ifdef NDEBUG
+ #define REG_JNI(name) { name }
+ struct RegJNIRec {
+ int (*mProc)(JNIEnv*);
+ };
+#else
+ #define REG_JNI(name) { name, #name }
+ struct RegJNIRec {
+ int (*mProc)(JNIEnv*);
+ const char* mName;
+ };
+#endif
+
+static const RegJNIRec gRegJNI[] = {
+ REG_JNI(register_android_graphics_Canvas),
+ // This needs to be before register_android_graphics_Graphics, or the latter
+ // will not be able to find the jmethodID for ColorSpace.get().
+ REG_JNI(register_android_graphics_ColorSpace),
+ REG_JNI(register_android_graphics_Graphics),
+ REG_JNI(register_android_graphics_Bitmap),
+ REG_JNI(register_android_graphics_BitmapFactory),
+ REG_JNI(register_android_graphics_BitmapRegionDecoder),
+ REG_JNI(register_android_graphics_ByteBufferStreamAdaptor),
+ REG_JNI(register_android_graphics_Camera),
+ REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
+ REG_JNI(register_android_graphics_CanvasProperty),
+ REG_JNI(register_android_graphics_ColorFilter),
+ REG_JNI(register_android_graphics_DrawFilter),
+ REG_JNI(register_android_graphics_FontFamily),
+ REG_JNI(register_android_graphics_HardwareRendererObserver),
+ REG_JNI(register_android_graphics_ImageDecoder),
+ REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable),
+ REG_JNI(register_android_graphics_Interpolator),
+ REG_JNI(register_android_graphics_MaskFilter),
+ REG_JNI(register_android_graphics_Matrix),
+ REG_JNI(register_android_graphics_Movie),
+ REG_JNI(register_android_graphics_NinePatch),
+ REG_JNI(register_android_graphics_Paint),
+ REG_JNI(register_android_graphics_Path),
+ REG_JNI(register_android_graphics_PathMeasure),
+ REG_JNI(register_android_graphics_PathEffect),
+ REG_JNI(register_android_graphics_Picture),
+ REG_JNI(register_android_graphics_Region),
+ REG_JNI(register_android_graphics_Shader),
+ REG_JNI(register_android_graphics_Typeface),
+ REG_JNI(register_android_graphics_YuvImage),
+ REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory),
+ REG_JNI(register_android_graphics_animation_RenderNodeAnimator),
+ REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable),
+ REG_JNI(register_android_graphics_drawable_VectorDrawable),
+ REG_JNI(register_android_graphics_fonts_Font),
+ REG_JNI(register_android_graphics_fonts_FontFamily),
+ REG_JNI(register_android_graphics_pdf_PdfDocument),
+ REG_JNI(register_android_graphics_pdf_PdfEditor),
+ REG_JNI(register_android_graphics_pdf_PdfRenderer),
+ REG_JNI(register_android_graphics_text_MeasuredText),
+ REG_JNI(register_android_graphics_text_LineBreaker),
+
+ REG_JNI(register_android_util_PathParser),
+ REG_JNI(register_android_view_RenderNode),
+ REG_JNI(register_android_view_DisplayListCanvas),
+ REG_JNI(register_android_view_TextureLayer),
+ REG_JNI(register_android_view_ThreadedRenderer),
+};
+
+} // namespace android
+
+void init_android_graphics() {
+ SkGraphics::Init();
+}
+
+int register_android_graphics_classes(JNIEnv *env) {
+ JavaVM* vm = nullptr;
+ env->GetJavaVM(&vm);
+ GraphicsJNI::setJavaVM(vm);
+
+ for (size_t i = 0; i < NELEM(android::gRegJNI); i++) {
+ if (android::gRegJNI[i].mProc(env) < 0) {
+#ifndef NDEBUG
+ __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "JNI Error!!! %s failed to load\n",
+ android::gRegJNI[i].mName);
+#endif
+ return -1;
+ }
+ }
+ return 0;
+}
+
+using android::uirenderer::Properties;
+using android::uirenderer::RenderPipelineType;
+
+void zygote_preload_graphics() {
+ if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) {
+ eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ }
+} \ No newline at end of file
diff --git a/libs/hwui/apex/renderthread.cpp b/libs/hwui/apex/renderthread.cpp
new file mode 100644
index 000000000000..5d26afe7a2ab
--- /dev/null
+++ b/libs/hwui/apex/renderthread.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 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 "android/graphics/renderthread.h"
+
+#include <renderthread/RenderProxy.h>
+
+using namespace android;
+
+void ARenderThread_dumpGraphicsMemory(int fd) {
+ uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd);
+}