diff options
-rw-r--r-- | core/jni/RobolectricNativeRuntime.cpp | 6 | ||||
-rw-r--r-- | core/jni/android_view_Surface.cpp | 8 | ||||
-rw-r--r-- | libs/hostgraphics/ANativeWindow.cpp | 6 | ||||
-rw-r--r-- | libs/hostgraphics/gui/Surface.h | 5 | ||||
-rw-r--r-- | libs/hwui/Android.bp | 9 | ||||
-rw-r--r-- | libs/hwui/RootRenderNode.cpp | 21 | ||||
-rw-r--r-- | libs/hwui/RootRenderNode.h | 2 | ||||
-rw-r--r-- | libs/hwui/apex/android_bitmap.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/apex/android_canvas.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/jni/BitmapFactory.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 16 | ||||
-rw-r--r-- | libs/hwui/jni/text/LineBreaker.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 43 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.h | 6 | ||||
-rw-r--r-- | libs/hwui/utils/Color.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/utils/Color.h | 2 | ||||
-rw-r--r-- | media/jni/android_media_ImageReader.cpp | 32 |
17 files changed, 100 insertions, 72 deletions
diff --git a/core/jni/RobolectricNativeRuntime.cpp b/core/jni/RobolectricNativeRuntime.cpp index d11a4b71ecef..fcbc89e788fb 100644 --- a/core/jni/RobolectricNativeRuntime.cpp +++ b/core/jni/RobolectricNativeRuntime.cpp @@ -4,6 +4,7 @@ #include <vector> #include <android/graphics/jni_runtime.h> +#include <locale.h> #include <sys/stat.h> #include <unicode/putil.h> #include <unicode/udata.h> @@ -214,5 +215,10 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { } env->ReleaseStringUTFChars(stringPath, icuPath); env->ReleaseStringUTFChars(stringLanguageTag, languageTag); + + // Use minimal "C" locale for number format to ensure correct parsing of floats when using + // strtof (e.g. in PathParser). + setlocale(LC_NUMERIC, "C"); + return JNI_VERSION_1_6; } diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 7c78f7b09937..0190f9ecc0bf 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -60,9 +60,7 @@ namespace android { static const char* const IllegalArgumentException = "java/lang/IllegalArgumentException"; -#ifdef __ANDROID__ static const char* const OutOfResourcesException = "android/view/Surface$OutOfResourcesException"; -#endif static struct { jclass clazz; @@ -204,7 +202,6 @@ static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jlong n static jlong nativeLockCanvas(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) { -#ifdef __ANDROID__ // host does not support locking Canvas sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); if (!isSurfaceValid(surface)) { @@ -256,14 +253,10 @@ static jlong nativeLockCanvas(JNIEnv* env, jclass clazz, sp<Surface> lockedSurface(surface); lockedSurface->incStrong(&sRefBaseOwner); return (jlong) lockedSurface.get(); -#else - return (jlong)nativeObject; -#endif } static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj) { -#ifdef __ANDROID__ // host does not support locking Canvas sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); if (!isSurfaceValid(surface)) { return; @@ -278,7 +271,6 @@ static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, if (err < 0) { jniThrowException(env, IllegalArgumentException, NULL); } -#endif } static void nativeAllocateBuffers(JNIEnv* /* env */ , jclass /* clazz */, diff --git a/libs/hostgraphics/ANativeWindow.cpp b/libs/hostgraphics/ANativeWindow.cpp index b7b8732b3f0d..442a49ae48dd 100644 --- a/libs/hostgraphics/ANativeWindow.cpp +++ b/libs/hostgraphics/ANativeWindow.cpp @@ -92,6 +92,10 @@ int32_t ANativeWindow_getHeight(ANativeWindow* window) { return query(window, NATIVE_WINDOW_HEIGHT); } +int32_t ANativeWindow_getFormat(ANativeWindow* window) { + return query(window, NATIVE_WINDOW_FORMAT); +} + void ANativeWindow_acquire(ANativeWindow* window) { // incStrong/decStrong token must be the same, doesn't matter what it is window->incStrong((void*)ANativeWindow_acquire); @@ -100,4 +104,4 @@ void ANativeWindow_acquire(ANativeWindow* window) { void ANativeWindow_release(ANativeWindow* window) { // incStrong/decStrong token must be the same, doesn't matter what it is window->decStrong((void*)ANativeWindow_acquire); -}
\ No newline at end of file +} diff --git a/libs/hostgraphics/gui/Surface.h b/libs/hostgraphics/gui/Surface.h index 664657bff92d..170b3eeac779 100644 --- a/libs/hostgraphics/gui/Surface.h +++ b/libs/hostgraphics/gui/Surface.h @@ -61,6 +61,11 @@ public: status_t setDequeueTimeout(nsecs_t timeout) { return OK; } nsecs_t getLastDequeueStartTime() const { return 0; } + + int getBuffersDataSpace() { + return 0; + } + protected: virtual ~Surface() {} diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index e1c200562b49..a22c477a5ae0 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -265,6 +265,8 @@ cc_defaults { cppflags: ["-Wno-conversion-null"], srcs: [ + "apex/android_bitmap.cpp", + "apex/android_canvas.cpp", "apex/android_matrix.cpp", "apex/android_paint.cpp", "apex/android_region.cpp", @@ -275,8 +277,6 @@ cc_defaults { target: { android: { srcs: [ // sources that depend on android only libraries - "apex/android_bitmap.cpp", - "apex/android_canvas.cpp", "apex/jni_runtime.cpp", "apex/renderthread.cpp", ], @@ -402,7 +402,6 @@ cc_defaults { ], static_libs: [ - "libnativehelper_lazy", "libziparchive_for_incfs", ], @@ -431,6 +430,7 @@ cc_defaults { ], static_libs: [ "libgif", + "libnativehelper_lazy", "libstatslog_hwui", "libstatspull_lazy", "libstatssocket_lazy", @@ -443,6 +443,7 @@ cc_defaults { ], static_libs: [ "libandroidfw", + "libnativehelper", ], }, }, @@ -514,6 +515,7 @@ cc_defaults { "pipeline/skia/RenderNodeDrawable.cpp", "pipeline/skia/ReorderBarrierDrawables.cpp", "pipeline/skia/TransformCanvas.cpp", + "renderstate/RenderState.cpp", "renderthread/CanvasContext.cpp", "renderthread/DrawFrameTask.cpp", "renderthread/Frame.cpp", @@ -579,7 +581,6 @@ cc_defaults { "pipeline/skia/SkiaVulkanPipeline.cpp", "pipeline/skia/VkFunctorDrawable.cpp", "pipeline/skia/VkInteropFunctorDrawable.cpp", - "renderstate/RenderState.cpp", "renderthread/CacheManager.cpp", "renderthread/EglManager.cpp", "renderthread/VulkanManager.cpp", diff --git a/libs/hwui/RootRenderNode.cpp b/libs/hwui/RootRenderNode.cpp index ddbbf58b3071..cc1c2df0040d 100644 --- a/libs/hwui/RootRenderNode.cpp +++ b/libs/hwui/RootRenderNode.cpp @@ -48,6 +48,8 @@ private: uint32_t mRequestId; }; +#endif + void RootRenderNode::prepareTree(TreeInfo& info) { info.errorHandler = mErrorHandler.get(); @@ -236,10 +238,12 @@ void RootRenderNode::detachVectorDrawableAnimator(PropertyValuesAnimatorSet* ani // removal is necessary: the end time of animation will not change unless triggered by // user events, in which case the already posted listener's id will become stale, and // the onFinished callback will then be ignored. +#ifdef __ANDROID__ // Layoutlib does not support Looper sp<FinishAndInvokeListener> message = new FinishAndInvokeListener(anim); auto looper = Looper::getForThread(); LOG_ALWAYS_FATAL_IF(looper == nullptr, "Not on a looper thread?"); looper->sendMessageDelayed(ms2ns(remainingTimeInMs), message, 0); +#endif anim->clearOneShotListener(); } } @@ -285,22 +289,5 @@ private: AnimationContext* ContextFactoryImpl::createAnimationContext(renderthread::TimeLord& clock) { return new AnimationContextBridge(clock, mRootNode); } -#else - -void RootRenderNode::prepareTree(TreeInfo& info) { - info.errorHandler = mErrorHandler.get(); - info.updateWindowPositions = true; - RenderNode::prepareTree(info); - info.updateWindowPositions = false; - info.errorHandler = nullptr; -} - -void RootRenderNode::attachAnimatingNode(RenderNode* animatingNode) { } - -void RootRenderNode::destroy() { } - -void RootRenderNode::addVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) { } - -#endif } // namespace android::uirenderer diff --git a/libs/hwui/RootRenderNode.h b/libs/hwui/RootRenderNode.h index 1d3f5a8a51e0..7a5cda7041ed 100644 --- a/libs/hwui/RootRenderNode.h +++ b/libs/hwui/RootRenderNode.h @@ -74,7 +74,6 @@ private: void detachVectorDrawableAnimator(PropertyValuesAnimatorSet* anim); }; -#ifdef __ANDROID__ // Layoutlib does not support Animations class ContextFactoryImpl : public IContextFactory { public: explicit ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {} @@ -84,6 +83,5 @@ public: private: RootRenderNode* mRootNode; }; -#endif } // namespace android::uirenderer diff --git a/libs/hwui/apex/android_bitmap.cpp b/libs/hwui/apex/android_bitmap.cpp index 3780ba072308..861189470189 100644 --- a/libs/hwui/apex/android_bitmap.cpp +++ b/libs/hwui/apex/android_bitmap.cpp @@ -83,7 +83,7 @@ static uint32_t getAlphaFlags(const SkImageInfo& info) { switch (info.alphaType()) { case kUnknown_SkAlphaType: LOG_ALWAYS_FATAL("Bitmap has no alpha type"); - break; + return 0; case kOpaque_SkAlphaType: return ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE; case kPremul_SkAlphaType: @@ -296,9 +296,13 @@ int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const AHardwareBuffer* ABitmap_getHardwareBuffer(ABitmap* bitmapHandle) { Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle); +#ifdef __ANDROID__ AHardwareBuffer* buffer = bitmap->hardwareBuffer(); if (buffer) { AHardwareBuffer_acquire(buffer); } return buffer; +#else + return nullptr; +#endif } diff --git a/libs/hwui/apex/android_canvas.cpp b/libs/hwui/apex/android_canvas.cpp index 2a939efed9bb..6d726f09f62f 100644 --- a/libs/hwui/apex/android_canvas.cpp +++ b/libs/hwui/apex/android_canvas.cpp @@ -39,6 +39,7 @@ static bool convert(const ANativeWindow_Buffer* buffer, return false; } +#ifdef __ANDROID__ sk_sp<SkColorSpace> cs(uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace)); SkImageInfo imageInfo = uirenderer::ANativeWindowToImageInfo(*buffer, cs); size_t rowBytes = buffer->stride * imageInfo.bytesPerPixel(); @@ -53,6 +54,7 @@ static bool convert(const ANativeWindow_Buffer* buffer, } return true; } +#endif return false; } diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp index dca865d2971c..73b5c19f369e 100644 --- a/libs/hwui/jni/BitmapFactory.cpp +++ b/libs/hwui/jni/BitmapFactory.cpp @@ -529,11 +529,13 @@ static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteA // Gets the 'handle' field from a FileDescriptor object. This field is only // populated in Windows. +#ifdef _WIN32 static jlong jniGetHandleFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) { jclass fileDescriptorClass = android::FindClassOrDie(env, "java/io/FileDescriptor"); jfieldID handleField = android::GetFieldIDOrDie(env, fileDescriptorClass, "handle", "J"); return env->GetLongField(fileDescriptor, handleField); } +#endif static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fileDescriptor, jobject padding, jobject bitmapFactoryOptions, jlong inBitmapHandle, jlong colorSpaceHandle) { diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index 759ef52f9b6d..07e20b569a3e 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -190,13 +190,9 @@ static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, job static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz, jboolean translucent, jlong rootRenderNodePtr) { RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr); -#ifdef __ANDROID__ // Layoutlib does not support Animation ContextFactoryImpl factory(rootRenderNode); RenderProxy* proxy = new RenderProxy(translucent, rootRenderNode, &factory); return (jlong) proxy; -#else - return (jlong) new RenderProxy(translucent, rootRenderNode, nullptr); -#endif } static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz, @@ -293,9 +289,15 @@ static void android_view_ThreadedRenderer_setIsHighEndGfx(JNIEnv* env, jobject c static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz, jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) { - LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE, + size_t expectedFrameInfoSize = UI_THREAD_FRAME_INFO_SIZE; + int robolectricApiLevel = GetRobolectricApiLevel(env); + // In Q and R (SDK 29 and 30), FrameInfo has size 9. + if (robolectricApiLevel == 29 || robolectricApiLevel == 30) { + expectedFrameInfoSize = 9; // From FrameInfo.h in Android Q + } + LOG_ALWAYS_FATAL_IF(frameInfoSize != expectedFrameInfoSize, "Mismatched size expectations, given %d expected %zu", frameInfoSize, - UI_THREAD_FRAME_INFO_SIZE); + expectedFrameInfoSize); RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo()); return proxy->syncAndDrawFrame(); @@ -697,14 +699,12 @@ static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, return result; } -#ifdef __ANDROID__ // Layoutlib does not support Animation class ContextFactory : public IContextFactory { public: virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) { return new AnimationContext(clock); } }; -#endif static jobject android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode(JNIEnv* env, jobject clazz, jlong renderNodePtr, jint jwidth, jint jheight) { diff --git a/libs/hwui/jni/text/LineBreaker.cpp b/libs/hwui/jni/text/LineBreaker.cpp index 279cecb88527..68e47ff02aa9 100644 --- a/libs/hwui/jni/text/LineBreaker.cpp +++ b/libs/hwui/jni/text/LineBreaker.cpp @@ -83,7 +83,7 @@ static jlong nGetReleaseFunc(CRITICAL_JNI_PARAMS) { return reinterpret_cast<jlong>(nFinish); } -static void nFinishP(CRITICAL_JNI_PARAMS, jlong nativePtr) { +static void nFinishP(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { nFinish(nativePtr); } diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 54ba6ac9638d..7df18d5cc691 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -96,7 +96,7 @@ CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent, } return nullptr; #else - return new CanvasContext(thread, translucent, rootRenderNode, nullptr, + return new CanvasContext(thread, translucent, rootRenderNode, contextFactory, std::make_unique<skiapipeline::SkiaHostPipeline>(thread)); #endif } @@ -129,8 +129,8 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* : mRenderThread(thread) , mGenerationID(0) , mOpaque(!translucent) -#ifdef __ANDROID__ // Layoutlib does not support Animations, Profiling, DeviceInfo , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord())) +#ifdef __ANDROID__ // Layoutlib does not support Profiling, DeviceInfo , mJankTracker(&thread.globalProfileData()) , mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos()) #endif @@ -169,9 +169,7 @@ void CanvasContext::destroy() { setSurfaceControl(nullptr); freePrefetchedLayers(); destroyHardwareResources(); -#ifdef __ANDROID__ // Layoutlib does not support Animations mAnimationContext->destroy(); -#endif } static void setBufferCount(ANativeWindow* window) { @@ -215,6 +213,7 @@ void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) { setASurfaceTransactionCallback(nullptr); setPrepareSurfaceControlForWebviewCallback(nullptr); } + if (mSurfaceControl != nullptr) { funcs.unregisterListenerFunc(this, &onSurfaceStatsAvailable); funcs.releaseFunc(mSurfaceControl); @@ -388,9 +387,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy info.damageGenerationId = mDamageId++; info.out.canDrawThisFrame = true; -#ifdef __ANDROID__ // Layoutlib does not support Animation mAnimationContext->startFrame(info.mode); -#endif for (const sp<RenderNode>& node : mRenderNodes) { // Only the primary target node will be drawn full - all other nodes would get drawn in // real time mode. In case of a window, the primary node is the window content and the other @@ -401,8 +398,8 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy GL_CHECKPOINT(MODERATE); #endif } -#ifdef __ANDROID__ // Layoutlib does not support Animation, GPU mAnimationContext->runRemainingAnimations(info); +#ifdef __ANDROID__ // Layoutlib does not support GPU GL_CHECKPOINT(MODERATE); freePrefetchedLayers(); @@ -440,7 +437,6 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy info.out.canDrawThisFrame = false; } -#ifdef __ANDROID__ // Layoutlib does not support Frame Callbacks if (info.out.canDrawThisFrame) { int err = mNativeSurface->reserveNext(); if (err != OK) { @@ -486,15 +482,12 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy }); } } -#endif } void CanvasContext::stopDrawing() { cleanupResources(); mRenderThread.removeFrameCallback(this); -#ifdef __ANDROID__ // Layoutlib does not support Animation mAnimationContext->pauseAnimators(); -#endif mGenerationID++; } @@ -695,9 +688,12 @@ void CanvasContext::cleanupResources() { void CanvasContext::reportMetricsWithPresentTime() { #ifdef __ANDROID__ // Layoutlib does not support FrameMetrics - if (mFrameMetricsReporter == nullptr) { - return; - } + { // acquire lock + std::scoped_lock lock(mFrameMetricsReporterMutex); + if (mFrameMetricsReporter == nullptr) { + return; + } + } // release lock if (mNativeSurface == nullptr) { return; } @@ -723,10 +719,27 @@ void CanvasContext::reportMetricsWithPresentTime() { nullptr /*outReleaseTime*/); forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime; - mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/); + { // acquire lock + std::scoped_lock lock(mFrameMetricsReporterMutex); + if (mFrameMetricsReporter != nullptr) { + mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/); + } + } // release lock #endif } +FrameInfo* CanvasContext::getFrameInfoFromLast4(uint64_t frameNumber) { +#ifdef __ANDROID__ // Layoutlib does not support Profiling + std::scoped_lock lock(mLast4FrameInfosMutex); + for (size_t i = 0; i < mLast4FrameInfos.size(); i++) { + if (mLast4FrameInfos[i].second == frameNumber) { + return mLast4FrameInfos[i].first; + } + } +#endif + return nullptr; +} + void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* control, ASurfaceControlStats* stats) { #ifdef __ANDROID__ // Layoutlib does not support surface control diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index b590867b7e57..0f30796d7ae1 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -283,7 +283,6 @@ enum class CopyResult { class RenderThread { PREVENT_COPY_AND_ASSIGN(RenderThread); - public: static void setOnStartHook(JVMAttachHook onStartHook) {} @@ -312,6 +311,11 @@ public: } template <class F> + void postDelayed(nsecs_t delay, F&& func) { + // We cannot do a delayed function call, let it be a noop as for now + } + + template <class F> auto runSync(F&& func) -> decltype(func()) { return func(); }; diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp index 5d9f2297c15a..35b0967a315c 100644 --- a/libs/hwui/utils/Color.cpp +++ b/libs/hwui/utils/Color.cpp @@ -19,10 +19,8 @@ #include <ui/ColorSpace.h> #include <utils/Log.h> -#ifdef __ANDROID__ // Layoutlib does not support hardware buffers or native windows #include <android/hardware_buffer.h> #include <android/native_window.h> -#endif #include <algorithm> #include <cmath> @@ -31,7 +29,6 @@ namespace android { namespace uirenderer { -#ifdef __ANDROID__ // Layoutlib does not support hardware buffers or native windows static inline SkImageInfo createImageInfo(int32_t width, int32_t height, int32_t format, sk_sp<SkColorSpace> colorSpace) { SkColorType colorType = kUnknown_SkColorType; @@ -95,7 +92,6 @@ uint32_t ColorTypeToBufferFormat(SkColorType colorType) { return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; } } -#endif namespace { static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h index 1654072fd264..15b4519d1889 100644 --- a/libs/hwui/utils/Color.h +++ b/libs/hwui/utils/Color.h @@ -90,7 +90,6 @@ static constexpr float EOCF_sRGB(float srgb) { return srgb <= 0.04045f ? srgb / 12.92f : powf((srgb + 0.055f) / 1.055f, 2.4f); } -#ifdef __ANDROID__ // Layoutlib does not support hardware buffers or native windows SkImageInfo ANativeWindowToImageInfo(const ANativeWindow_Buffer& buffer, sk_sp<SkColorSpace> colorSpace); @@ -98,7 +97,6 @@ SkImageInfo BufferDescriptionToImageInfo(const AHardwareBuffer_Desc& bufferDesc, sk_sp<SkColorSpace> colorSpace); uint32_t ColorTypeToBufferFormat(SkColorType colorType); -#endif ANDROID_API sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace); diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index b9deafab588b..80b3c719c596 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -306,6 +306,18 @@ static BufferItem* Image_getBufferItem(JNIEnv* env, jobject image) } +static inline int GetRobolectricApiLevel(JNIEnv* env) { + jclass runtimeEnvironment = env->FindClass("org/robolectric/RuntimeEnvironment"); + LOG_ALWAYS_FATAL_IF(runtimeEnvironment == NULL, + "can't find org/robolectric/RuntimeEnvironment"); + jmethodID getApiLevelMethod =env->GetStaticMethodID( + runtimeEnvironment, "getApiLevel", "()I"); + LOG_ALWAYS_FATAL_IF(getApiLevelMethod == NULL, + "can't find org/robolectric/RuntimeEnvironment.getApiLevel"); + return (jint)env->CallStaticIntMethod(runtimeEnvironment, getApiLevelMethod); +} + + // ---------------------------------------------------------------------------- static void ImageReader_classInit(JNIEnv* env, jclass clazz) @@ -364,14 +376,18 @@ static void ImageReader_classInit(JNIEnv* env, jclass clazz) LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, "Can not find SurfacePlane constructor"); - planeClazz = env->FindClass("android/media/ImageReader$ImagePlane"); - LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find ImagePlane class"); - // FindClass only gives a local reference of jclass object. - gImagePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); - gImagePlaneClassInfo.ctor = env->GetMethodID(gImagePlaneClassInfo.clazz, "<init>", - "(IILjava/nio/ByteBuffer;)V"); - LOG_ALWAYS_FATAL_IF(gImagePlaneClassInfo.ctor == NULL, - "Can not find ImagePlane constructor"); + int robolectricApiLevel = GetRobolectricApiLevel(env); + // ImageReader$ImagePlane was introduced in Android S (SDK 31). + if (robolectricApiLevel >= 31) { + planeClazz = env->FindClass("android/media/ImageReader$ImagePlane"); + LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find ImagePlane class"); + // FindClass only gives a local reference of jclass object. + gImagePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); + gImagePlaneClassInfo.ctor = env->GetMethodID(gImagePlaneClassInfo.clazz, "<init>", + "(IILjava/nio/ByteBuffer;)V"); + LOG_ALWAYS_FATAL_IF(gImagePlaneClassInfo.ctor == NULL, + "Can not find ImagePlane constructor"); + } } static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint width, jint height, |