diff options
Diffstat (limited to 'libs/hwui/apex')
-rw-r--r-- | libs/hwui/apex/LayoutlibLoader.cpp | 191 | ||||
-rw-r--r-- | libs/hwui/apex/TypeCast.h | 70 | ||||
-rw-r--r-- | libs/hwui/apex/android_bitmap.cpp | 304 | ||||
-rw-r--r-- | libs/hwui/apex/android_canvas.cpp | 109 | ||||
-rw-r--r-- | libs/hwui/apex/android_matrix.cpp | 37 | ||||
-rw-r--r-- | libs/hwui/apex/android_paint.cpp | 47 | ||||
-rw-r--r-- | libs/hwui/apex/android_region.cpp | 60 | ||||
-rw-r--r-- | libs/hwui/apex/include/android/graphics/bitmap.h | 146 | ||||
-rw-r--r-- | libs/hwui/apex/include/android/graphics/canvas.h | 142 | ||||
-rw-r--r-- | libs/hwui/apex/include/android/graphics/jni_runtime.h | 35 | ||||
-rw-r--r-- | libs/hwui/apex/include/android/graphics/matrix.h | 39 | ||||
-rw-r--r-- | libs/hwui/apex/include/android/graphics/paint.h | 67 | ||||
-rw-r--r-- | libs/hwui/apex/include/android/graphics/region.h | 77 | ||||
-rw-r--r-- | libs/hwui/apex/include/android/graphics/renderthread.h | 34 | ||||
-rw-r--r-- | libs/hwui/apex/jni_runtime.cpp | 177 | ||||
-rw-r--r-- | libs/hwui/apex/renderthread.cpp | 25 |
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); +} |