From 6db59a66bdcdad7e4c565e47c31437860455e832 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Fri, 2 Aug 2019 17:05:26 -0700 Subject: [HWUI] clean up libgui include directives As a first pass removing some stale includes. Bug: 138819035 Change-Id: I7aef319aa8f1b13b6482ef61fda151560e570558 Test: builds --- libs/hwui/DeviceInfo.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'libs/hwui/DeviceInfo.cpp') diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp index 0a9d965d0444..a0d3ff995e78 100644 --- a/libs/hwui/DeviceInfo.cpp +++ b/libs/hwui/DeviceInfo.cpp @@ -18,7 +18,6 @@ #include "Properties.h" -#include #include #include -- cgit v1.2.3-59-g8ed1b From 22d753f74d83bec10fc05a04156adaf76430d540 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 5 Sep 2019 17:11:45 -0700 Subject: [HWUI] Get DeviceInfo through stable ABI This also removes the dependency on ui/DeviceInfo other than in test code. Bug: 136263392 Bug: 136263238 Test: builds, boots Change-Id: I6a4687e981359f0e6beb83be8a5501ed7fd16f15 --- core/jni/Android.bp | 2 + libs/hwui/Android.bp | 1 + libs/hwui/DeviceInfo.cpp | 101 ++++++++++++----------------- libs/hwui/DeviceInfo.h | 26 ++++++-- libs/hwui/JankTracker.cpp | 14 ++-- libs/hwui/JankTracker.h | 3 +- libs/hwui/Properties.cpp | 1 - libs/hwui/RenderProperties.h | 3 + libs/hwui/renderthread/CacheManager.cpp | 9 +-- libs/hwui/renderthread/CacheManager.h | 3 +- libs/hwui/renderthread/CanvasContext.cpp | 4 +- libs/hwui/renderthread/RenderThread.cpp | 5 +- libs/hwui/renderthread/RenderThread.h | 1 - libs/hwui/tests/unit/CacheManagerTests.cpp | 8 +-- 14 files changed, 89 insertions(+), 92 deletions(-) (limited to 'libs/hwui/DeviceInfo.cpp') diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 0505fe30c55c..6ba96996ef5c 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -260,6 +260,7 @@ cc_library_shared { "libhidltransport", "libhwbinder", "libvintf", + "libnativedisplay", "libnativewindow", "libdl", "libdl_android", @@ -439,6 +440,7 @@ cc_library_static { ], shared_libs: [ "libandroidfw", + "libnativedisplay", "libnativewindow", "libgui", "libpdfium", diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index ae90f117d448..b19aa2ff5862 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -88,6 +88,7 @@ cc_defaults { "libvulkan", "libui", "libgui", + "libnativedisplay", "libnativewindow", "libprotobuf-cpp-lite", "libft2", diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp index a0d3ff995e78..41e9b4be6649 100644 --- a/libs/hwui/DeviceInfo.cpp +++ b/libs/hwui/DeviceInfo.cpp @@ -15,74 +15,21 @@ */ #include - -#include "Properties.h" - #include +#include #include #include #include -#include +#include "Properties.h" namespace android { namespace uirenderer { -static constexpr android::DisplayInfo sDummyDisplay{ - 1080, // w - 1920, // h - 320.0, // xdpi - 320.0, // ydpi - 60.0, // fps - 2.0, // density - 0, // orientation - false, // secure? - 0, // appVsyncOffset - 0, // presentationDeadline - 1080, // viewportW - 1920, // viewportH -}; - DeviceInfo* DeviceInfo::get() { - static DeviceInfo sDeviceInfo; - return &sDeviceInfo; -} - -static DisplayInfo QueryDisplayInfo() { - if (Properties::isolatedProcess) { - return sDummyDisplay; - } - - const sp token = SurfaceComposerClient::getInternalDisplayToken(); - LOG_ALWAYS_FATAL_IF(token == nullptr, - "Failed to get display info because internal display is disconnected"); - - DisplayInfo displayInfo; - status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo); - LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status); - return displayInfo; -} - -static float QueryMaxRefreshRate() { - if (Properties::isolatedProcess) { - return sDummyDisplay.fps; - } - - const sp token = SurfaceComposerClient::getInternalDisplayToken(); - LOG_ALWAYS_FATAL_IF(token == nullptr, - "Failed to get display info because internal display is disconnected"); - - Vector configs; - configs.reserve(10); - status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs); - LOG_ALWAYS_FATAL_IF(status, "Failed to getDisplayConfigs, error %d", status); - LOG_ALWAYS_FATAL_IF(configs.size() == 0, "getDisplayConfigs returned 0 configs?"); - float max = 0.0f; - for (auto& info : configs) { - max = std::max(max, info.fps); - } - return max; + static DeviceInfo sDeviceInfo; + return &sDeviceInfo; } static void queryWideColorGamutPreference(sk_sp* colorSpace, SkColorType* colorType) { @@ -123,14 +70,17 @@ static void queryWideColorGamutPreference(sk_sp* colorSpace, SkCol } } -DeviceInfo::DeviceInfo() : mMaxRefreshRate(QueryMaxRefreshRate()) { +DeviceInfo::DeviceInfo() { #if HWUI_NULL_GPU mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE; #else mMaxTextureSize = -1; #endif - mDisplayInfo = QueryDisplayInfo(); - queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType); + updateDisplayInfo(); + queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType); +} +DeviceInfo::~DeviceInfo() { + ADisplay_release(mDisplays); } int DeviceInfo::maxTextureSize() const { @@ -143,7 +93,36 @@ void DeviceInfo::setMaxTextureSize(int maxTextureSize) { } void DeviceInfo::onDisplayConfigChanged() { - mDisplayInfo = QueryDisplayInfo(); + updateDisplayInfo(); +} + +void DeviceInfo::updateDisplayInfo() { + if (Properties::isolatedProcess) { + return; + } + + if (mCurrentConfig == nullptr) { + mDisplaysSize = ADisplay_acquirePhysicalDisplays(&mDisplays); + LOG_ALWAYS_FATAL_IF(mDisplays == nullptr || mDisplaysSize <= 0, + "Failed to get physical displays: no connected display: %d!", mDisplaysSize); + for (size_t i = 0; i < mDisplaysSize; i++) { + ADisplayType type = ADisplay_getDisplayType(mDisplays[i]); + if (type == ADisplayType::DISPLAY_TYPE_INTERNAL) { + mPhysicalDisplayIndex = i; + break; + } + } + LOG_ALWAYS_FATAL_IF(mPhysicalDisplayIndex < 0, "Failed to find a connected physical display!"); + mMaxRefreshRate = ADisplay_getMaxSupportedFps(mDisplays[mPhysicalDisplayIndex]); + } + status_t status = ADisplay_getCurrentConfig(mDisplays[mPhysicalDisplayIndex], &mCurrentConfig); + LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status); + mWidth = ADisplayConfig_getWidth(mCurrentConfig); + mHeight = ADisplayConfig_getHeight(mCurrentConfig); + mDensity = ADisplayConfig_getDensity(mCurrentConfig); + mRefreshRate = ADisplayConfig_getFps(mCurrentConfig); + mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig); + mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig); } } /* namespace uirenderer */ diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h index 0e3f11960ddc..34315830ed97 100644 --- a/libs/hwui/DeviceInfo.h +++ b/libs/hwui/DeviceInfo.h @@ -16,8 +16,8 @@ #ifndef DEVICEINFO_H #define DEVICEINFO_H +#include #include -#include #include "utils/Macros.h" @@ -33,28 +33,44 @@ class DeviceInfo { public: static DeviceInfo* get(); + static float getMaxRefreshRate() { return get()->mMaxRefreshRate; } + static int32_t getWidth() { return get()->mWidth; } + static int32_t getHeight() { return get()->mHeight; } + static float getDensity() { return get()->mDensity; } + static float getRefreshRate() { return get()->mRefreshRate; } + static int64_t getCompositorOffset() { return get()->mCompositorOffset; } + static int64_t getAppOffset() { return get()->mAppOffset; } // this value is only valid after the GPU has been initialized and there is a valid graphics // context or if you are using the HWUI_NULL_GPU int maxTextureSize() const; - const DisplayInfo& displayInfo() const { return mDisplayInfo; } sk_sp getWideColorSpace() const { return mWideColorSpace; } SkColorType getWideColorType() const { return mWideColorType; } - float getMaxRefreshRate() const { return mMaxRefreshRate; } void onDisplayConfigChanged(); private: friend class renderthread::RenderThread; static void setMaxTextureSize(int maxTextureSize); + void updateDisplayInfo(); DeviceInfo(); + ~DeviceInfo(); int mMaxTextureSize; - DisplayInfo mDisplayInfo; sk_sp mWideColorSpace; SkColorType mWideColorType; - const float mMaxRefreshRate; + ADisplayConfig* mCurrentConfig = nullptr; + ADisplay** mDisplays = nullptr; + int mDisplaysSize = 0; + int mPhysicalDisplayIndex = -1; + float mMaxRefreshRate = 60.0; + int32_t mWidth = 1080; + int32_t mHeight = 1920; + float mDensity = 2.0; + float mRefreshRate = 60.0; + int64_t mCompositorOffset = 0; + int64_t mAppOffset = 0; }; } /* namespace uirenderer */ diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index eae3584465e4..10e7160e7069 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -16,8 +16,10 @@ #include "JankTracker.h" +#include #include #include +#include #include #include @@ -25,11 +27,9 @@ #include #include #include - -#include -#include #include +#include "DeviceInfo.h" #include "Properties.h" #include "utils/TimeUtils.h" #include "utils/Trace.h" @@ -79,11 +79,11 @@ static const int64_t EXEMPT_FRAMES_FLAGS = FrameInfoFlags::SurfaceCanvas; // and filter it out of the frame profile data static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync; -JankTracker::JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo) { +JankTracker::JankTracker(ProfileDataContainer* globalData) { mGlobalData = globalData; - nsecs_t frameIntervalNanos = static_cast(1_s / displayInfo.fps); - nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms); - nsecs_t offsetDelta = sfOffset - displayInfo.appVsyncOffset; + nsecs_t frameIntervalNanos = static_cast(1_s / DeviceInfo::getRefreshRate()); + nsecs_t sfOffset = DeviceInfo::getCompositorOffset(); + nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset(); // There are two different offset cases. If the offsetDelta is positive // and small, then the intention is to give apps extra time by leveraging // pipelining between the UI & RT threads. If the offsetDelta is large or diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h index 08059268f03e..4460266276f9 100644 --- a/libs/hwui/JankTracker.h +++ b/libs/hwui/JankTracker.h @@ -23,7 +23,6 @@ #include "utils/RingBuffer.h" #include -#include #include #include @@ -49,7 +48,7 @@ struct ProfileDataDescription { // TODO: Replace DrawProfiler with this class JankTracker { public: - explicit JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo); + explicit JankTracker(ProfileDataContainer* globalData); void setDescription(JankTrackerType type, const std::string&& name) { mDescription.type = type; diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 4e7df88b8095..446e81e65bb8 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -16,7 +16,6 @@ #include "Properties.h" #include "Debug.h" -#include "DeviceInfo.h" #ifdef __ANDROID__ #include "HWUIProperties.sysprop.h" #endif diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index e9794489f171..24f6035b6708 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -16,7 +16,10 @@ #pragma once +#ifdef __ANDROID__ // Layoutlib does not support device info #include "DeviceInfo.h" +#endif // __ANDROID__ + #include "Outline.h" #include "Rect.h" #include "RevealClip.h" diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp index dc07f0d84d18..b78c50a4b66d 100644 --- a/libs/hwui/renderthread/CacheManager.cpp +++ b/libs/hwui/renderthread/CacheManager.cpp @@ -16,6 +16,7 @@ #include "CacheManager.h" +#include "DeviceInfo.h" #include "Layer.h" #include "Properties.h" #include "RenderThread.h" @@ -42,8 +43,8 @@ namespace renderthread { #define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f) #define BACKGROUND_RETENTION_PERCENTAGE (0.5f) -CacheManager::CacheManager(const DisplayInfo& display) - : mMaxSurfaceArea(display.w * display.h) +CacheManager::CacheManager() + : mMaxSurfaceArea(DeviceInfo::getWidth() * DeviceInfo::getHeight()) , mMaxResourceBytes(mMaxSurfaceArea * SURFACE_SIZE_MULTIPLIER) , mBackgroundResourceBytes(mMaxResourceBytes * BACKGROUND_RETENTION_PERCENTAGE) // This sets the maximum size for a single texture atlas in the GPU font cache. If @@ -52,9 +53,9 @@ CacheManager::CacheManager(const DisplayInfo& display) , mMaxGpuFontAtlasBytes(GrNextSizePow2(mMaxSurfaceArea)) // This sets the maximum size of the CPU font cache to be at least the same size as the // total number of GPU font caches (i.e. 4 separate GPU atlases). - , mMaxCpuFontCacheBytes(std::max(mMaxGpuFontAtlasBytes*4, SkGraphics::GetFontCacheLimit())) + , mMaxCpuFontCacheBytes( + std::max(mMaxGpuFontAtlasBytes * 4, SkGraphics::GetFontCacheLimit())) , mBackgroundCpuFontCacheBytes(mMaxCpuFontCacheBytes * BACKGROUND_RETENTION_PERCENTAGE) { - SkGraphics::SetFontCacheLimit(mMaxCpuFontCacheBytes); mVectorDrawableAtlas = new skiapipeline::VectorDrawableAtlas( diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h index d7977cc4566d..dacb7bdb9207 100644 --- a/libs/hwui/renderthread/CacheManager.h +++ b/libs/hwui/renderthread/CacheManager.h @@ -21,7 +21,6 @@ #include #endif #include -#include #include #include @@ -59,7 +58,7 @@ public: private: friend class RenderThread; - explicit CacheManager(const DisplayInfo& display); + explicit CacheManager(); #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration void reset(sk_sp grContext); diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 93fd0c87a361..323f622cdb0a 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -102,13 +102,13 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* , mGenerationID(0) , mOpaque(!translucent) , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord())) - , mJankTracker(&thread.globalProfileData(), DeviceInfo::get()->displayInfo()) + , mJankTracker(&thread.globalProfileData()) , mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos()) , mContentDrawBounds(0, 0, 0, 0) , mRenderPipeline(std::move(renderPipeline)) { rootRenderNode->makeRoot(); mRenderNodes.emplace_back(rootRenderNode); - mProfiler.setDensity(DeviceInfo::get()->displayInfo().density); + mProfiler.setDensity(DeviceInfo::getDensity()); setRenderAheadDepth(Properties::defaultRenderAhead); } diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index ee1a7ce19e82..a446858ca565 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -179,12 +179,11 @@ void RenderThread::initThreadLocals() { mEglManager = new EglManager(); mRenderState = new RenderState(*this); mVkManager = new VulkanManager(); - mCacheManager = new CacheManager(DeviceInfo::get()->displayInfo()); + mCacheManager = new CacheManager(); } void RenderThread::setupFrameInterval() { - auto& displayInfo = DeviceInfo::get()->displayInfo(); - nsecs_t frameIntervalNanos = static_cast(1000000000 / displayInfo.fps); + nsecs_t frameIntervalNanos = static_cast(1000000000 / DeviceInfo::getRefreshRate()); mTimeLord.setFrameInterval(frameIntervalNanos); mDispatchFrameDelay = static_cast(frameIntervalNanos * .25f); } diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index 5aa1af32094f..bdd80721c4f3 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp index 3f1ef93c878c..c83a3c88cbdd 100644 --- a/libs/hwui/tests/unit/CacheManagerTests.cpp +++ b/libs/hwui/tests/unit/CacheManagerTests.cpp @@ -33,7 +33,8 @@ static size_t getCacheUsage(GrContext* grContext) { } RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) { - DisplayInfo displayInfo = DeviceInfo::get()->displayInfo(); + int32_t width = DeviceInfo::get()->getWidth(); + int32_t height = DeviceInfo::get()->getHeight(); GrContext* grContext = renderThread.getGrContext(); ASSERT_TRUE(grContext != nullptr); @@ -42,7 +43,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) { std::vector> surfaces; while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) { - SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h); + SkImageInfo info = SkImageInfo::MakeA8(width, height); sk_sp surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info); surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT); @@ -52,8 +53,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) { } // create an image and pin it so that we have something with a unique key in the cache - sk_sp bitmap = - Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(displayInfo.w, displayInfo.h)); + sk_sp bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height)); sk_sp image = bitmap->makeImage(); ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext)); -- cgit v1.2.3-59-g8ed1b From 70f2a92e4fe79f5e527b06e3456ee3d09e550fb0 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Wed, 20 Nov 2019 11:10:29 -0800 Subject: [HWUI] Grab preferred WCG format from ADisplay * Removes the SurfaceComposerClient dependency from DeviceInfo * Removes libui dependencies from DeviceInfo. Bug: 144505134 Test: builds, boots, launch settings Change-Id: I5eb8b296ff274ca2affafedf6f2fd13fd75469b9 --- libs/hwui/DeviceInfo.cpp | 82 +++++++++++++++++++++++------------------------- libs/hwui/DeviceInfo.h | 4 +-- 2 files changed, 41 insertions(+), 45 deletions(-) (limited to 'libs/hwui/DeviceInfo.cpp') diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp index 41e9b4be6649..e53f3db08538 100644 --- a/libs/hwui/DeviceInfo.cpp +++ b/libs/hwui/DeviceInfo.cpp @@ -15,9 +15,8 @@ */ #include -#include #include -#include +#include #include #include @@ -32,44 +31,6 @@ DeviceInfo* DeviceInfo::get() { return &sDeviceInfo; } -static void queryWideColorGamutPreference(sk_sp* colorSpace, SkColorType* colorType) { - if (Properties::isolatedProcess) { - *colorSpace = SkColorSpace::MakeSRGB(); - *colorType = SkColorType::kN32_SkColorType; - return; - } - ui::Dataspace defaultDataspace, wcgDataspace; - ui::PixelFormat defaultPixelFormat, wcgPixelFormat; - status_t status = - SurfaceComposerClient::getCompositionPreference(&defaultDataspace, &defaultPixelFormat, - &wcgDataspace, &wcgPixelFormat); - LOG_ALWAYS_FATAL_IF(status, "Failed to get composition preference, error %d", status); - switch (wcgDataspace) { - case ui::Dataspace::DISPLAY_P3: - *colorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3); - break; - case ui::Dataspace::V0_SCRGB: - *colorSpace = SkColorSpace::MakeSRGB(); - break; - case ui::Dataspace::V0_SRGB: - // when sRGB is returned, it means wide color gamut is not supported. - *colorSpace = SkColorSpace::MakeSRGB(); - break; - default: - LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space."); - } - switch (wcgPixelFormat) { - case ui::PixelFormat::RGBA_8888: - *colorType = SkColorType::kN32_SkColorType; - break; - case ui::PixelFormat::RGBA_FP16: - *colorType = SkColorType::kRGBA_F16_SkColorType; - break; - default: - LOG_ALWAYS_FATAL("Unreachable: unsupported pixel format."); - } -} - DeviceInfo::DeviceInfo() { #if HWUI_NULL_GPU mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE; @@ -77,7 +38,6 @@ DeviceInfo::DeviceInfo() { mMaxTextureSize = -1; #endif updateDisplayInfo(); - queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType); } DeviceInfo::~DeviceInfo() { ADisplay_release(mDisplays); @@ -113,9 +73,45 @@ void DeviceInfo::updateDisplayInfo() { } } LOG_ALWAYS_FATAL_IF(mPhysicalDisplayIndex < 0, "Failed to find a connected physical display!"); - mMaxRefreshRate = ADisplay_getMaxSupportedFps(mDisplays[mPhysicalDisplayIndex]); + + + // Since we now just got the primary display for the first time, then + // store the primary display metadata here. + ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex]; + mMaxRefreshRate = ADisplay_getMaxSupportedFps(primaryDisplay); + ADataSpace dataspace; + AHardwareBuffer_Format format; + ADisplay_getPreferredWideColorFormat(primaryDisplay, &dataspace, &format); + switch (dataspace) { + case ADATASPACE_DISPLAY_P3: + mWideColorSpace = + SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3); + break; + case ADATASPACE_SCRGB: + mWideColorSpace = SkColorSpace::MakeSRGB(); + break; + case ADATASPACE_SRGB: + // when sRGB is returned, it means wide color gamut is not supported. + mWideColorSpace = SkColorSpace::MakeSRGB(); + break; + default: + LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space."); + } + switch (format) { + case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: + mWideColorType = SkColorType::kN32_SkColorType; + break; + case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: + mWideColorType = SkColorType::kRGBA_F16_SkColorType; + break; + default: + LOG_ALWAYS_FATAL("Unreachable: unsupported pixel format."); + } } - status_t status = ADisplay_getCurrentConfig(mDisplays[mPhysicalDisplayIndex], &mCurrentConfig); + // This method may have been called when the display config changed, so + // sync with the current configuration. + ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex]; + status_t status = ADisplay_getCurrentConfig(primaryDisplay, &mCurrentConfig); LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status); mWidth = ADisplayConfig_getWidth(mCurrentConfig); mHeight = ADisplayConfig_getHeight(mCurrentConfig); diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h index 34315830ed97..a4207460883e 100644 --- a/libs/hwui/DeviceInfo.h +++ b/libs/hwui/DeviceInfo.h @@ -58,8 +58,8 @@ private: ~DeviceInfo(); int mMaxTextureSize; - sk_sp mWideColorSpace; - SkColorType mWideColorType; + sk_sp mWideColorSpace = SkColorSpace::MakeSRGB(); + SkColorType mWideColorType = SkColorType::kN32_SkColorType; ADisplayConfig* mCurrentConfig = nullptr; ADisplay** mDisplays = nullptr; int mDisplaysSize = 0; -- cgit v1.2.3-59-g8ed1b From 4a818f189c910810d6be72147a4567d97ad7232a Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Tue, 19 Nov 2019 16:17:53 -0800 Subject: [HWUI] use AChoreographer in place of DisplayEventReceiver. Bug: 136262896 Test: builds, boots Test: scroll through settings app Test: Toggle between 60/90hz and observe systrace Change-Id: I8eef306a968525c55f3863ae688545faa43b23be --- libs/hwui/DeviceInfo.cpp | 7 +- libs/hwui/DeviceInfo.h | 7 +- libs/hwui/JankTracker.cpp | 2 +- libs/hwui/renderthread/RenderThread.cpp | 125 +++++++++++++------------------- libs/hwui/renderthread/RenderThread.h | 17 ++++- 5 files changed, 72 insertions(+), 86 deletions(-) (limited to 'libs/hwui/DeviceInfo.cpp') diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp index e53f3db08538..6d4a0c6421d9 100644 --- a/libs/hwui/DeviceInfo.cpp +++ b/libs/hwui/DeviceInfo.cpp @@ -52,8 +52,8 @@ void DeviceInfo::setMaxTextureSize(int maxTextureSize) { DeviceInfo::get()->mMaxTextureSize = maxTextureSize; } -void DeviceInfo::onDisplayConfigChanged() { - updateDisplayInfo(); +void DeviceInfo::onRefreshRateChanged(int64_t vsyncPeriod) { + mVsyncPeriod = vsyncPeriod; } void DeviceInfo::updateDisplayInfo() { @@ -113,10 +113,11 @@ void DeviceInfo::updateDisplayInfo() { ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex]; status_t status = ADisplay_getCurrentConfig(primaryDisplay, &mCurrentConfig); LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status); + mWidth = ADisplayConfig_getWidth(mCurrentConfig); mHeight = ADisplayConfig_getHeight(mCurrentConfig); mDensity = ADisplayConfig_getDensity(mCurrentConfig); - mRefreshRate = ADisplayConfig_getFps(mCurrentConfig); + mVsyncPeriod = static_cast(1000000000 / ADisplayConfig_getFps(mCurrentConfig)); mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig); mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig); } diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h index a4207460883e..16a22f4706f5 100644 --- a/libs/hwui/DeviceInfo.h +++ b/libs/hwui/DeviceInfo.h @@ -37,7 +37,7 @@ public: static int32_t getWidth() { return get()->mWidth; } static int32_t getHeight() { return get()->mHeight; } static float getDensity() { return get()->mDensity; } - static float getRefreshRate() { return get()->mRefreshRate; } + static int64_t getVsyncPeriod() { return get()->mVsyncPeriod; } static int64_t getCompositorOffset() { return get()->mCompositorOffset; } static int64_t getAppOffset() { return get()->mAppOffset; } @@ -47,7 +47,8 @@ public: sk_sp getWideColorSpace() const { return mWideColorSpace; } SkColorType getWideColorType() const { return mWideColorType; } - void onDisplayConfigChanged(); + // This method should be called whenever the display refresh rate changes. + void onRefreshRateChanged(int64_t vsyncPeriod); private: friend class renderthread::RenderThread; @@ -68,7 +69,7 @@ private: int32_t mWidth = 1080; int32_t mHeight = 1920; float mDensity = 2.0; - float mRefreshRate = 60.0; + int64_t mVsyncPeriod = 16666666; int64_t mCompositorOffset = 0; int64_t mAppOffset = 0; }; diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index 10e7160e7069..d25fc4b0b03e 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -81,7 +81,7 @@ static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync; JankTracker::JankTracker(ProfileDataContainer* globalData) { mGlobalData = globalData; - nsecs_t frameIntervalNanos = static_cast(1_s / DeviceInfo::getRefreshRate()); + nsecs_t frameIntervalNanos = DeviceInfo::getVsyncPeriod(); nsecs_t sfOffset = DeviceInfo::getCompositorOffset(); nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset(); // There are two different offset cases. If the offsetDelta is positive diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index a446858ca565..d78f641d45b9 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -45,53 +44,43 @@ namespace android { namespace uirenderer { namespace renderthread { -// Number of events to read at a time from the DisplayEventReceiver pipe. -// The value should be large enough that we can quickly drain the pipe -// using just a few large reads. -static const size_t EVENT_BUFFER_SIZE = 100; - static bool gHasRenderThreadInstance = false; static JVMAttachHook gOnStartHook = nullptr; -class DisplayEventReceiverWrapper : public VsyncSource { +void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) { + RenderThread* rt = reinterpret_cast(data); + rt->mVsyncRequested = false; + if (rt->timeLord().vsyncReceived(frameTimeNanos) && !rt->mFrameCallbackTaskPending) { + ATRACE_NAME("queue mFrameCallbackTask"); + rt->mFrameCallbackTaskPending = true; + nsecs_t runAt = (frameTimeNanos + rt->mDispatchFrameDelay); + rt->queue().postAt(runAt, [=]() { rt->dispatchFrameCallbacks(); }); + } +} + +void RenderThread::refreshRateCallback(int64_t vsyncPeriod, void* data) { + ATRACE_NAME("refreshRateCallback"); + RenderThread* rt = reinterpret_cast(data); + DeviceInfo::get()->onRefreshRateChanged(vsyncPeriod); + rt->setupFrameInterval(); +} + +class ChoreographerSource : public VsyncSource { public: - DisplayEventReceiverWrapper(std::unique_ptr&& receiver, - const std::function& onDisplayConfigChanged) - : mDisplayEventReceiver(std::move(receiver)) - , mOnDisplayConfigChanged(onDisplayConfigChanged) {} + ChoreographerSource(RenderThread* renderThread) : mRenderThread(renderThread) {} virtual void requestNextVsync() override { - status_t status = mDisplayEventReceiver->requestNextVsync(); - LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "requestNextVsync failed with status: %d", status); + AChoreographer_postFrameCallback64(mRenderThread->mChoreographer, + RenderThread::frameCallback, mRenderThread); } - virtual nsecs_t latestVsyncEvent() override { - DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; - nsecs_t latest = 0; - ssize_t n; - while ((n = mDisplayEventReceiver->getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { - for (ssize_t i = 0; i < n; i++) { - const DisplayEventReceiver::Event& ev = buf[i]; - switch (ev.header.type) { - case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: - latest = ev.header.timestamp; - break; - case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED: - mOnDisplayConfigChanged(); - break; - } - } - } - if (n < 0) { - ALOGW("Failed to get events from display event receiver, status=%d", status_t(n)); - } - return latest; + virtual void drainPendingEvents() override { + AChoreographer_handlePendingEvents(mRenderThread->mChoreographer, mRenderThread); } private: - std::unique_ptr mDisplayEventReceiver; - std::function mOnDisplayConfigChanged; + RenderThread* mRenderThread; }; class DummyVsyncSource : public VsyncSource { @@ -99,11 +88,14 @@ public: DummyVsyncSource(RenderThread* renderThread) : mRenderThread(renderThread) {} virtual void requestNextVsync() override { - mRenderThread->queue().postDelayed(16_ms, - [this]() { mRenderThread->drainDisplayEventQueue(); }); + mRenderThread->queue().postDelayed(16_ms, [this]() { + RenderThread::frameCallback(systemTime(SYSTEM_TIME_MONOTONIC), mRenderThread); + }); } - virtual nsecs_t latestVsyncEvent() override { return systemTime(SYSTEM_TIME_MONOTONIC); } + virtual void drainPendingEvents() override { + RenderThread::frameCallback(systemTime(SYSTEM_TIME_MONOTONIC), mRenderThread); + } private: RenderThread* mRenderThread; @@ -145,29 +137,24 @@ RenderThread::RenderThread() } RenderThread::~RenderThread() { + // Note that if this fatal assertion is removed then member variables must + // be properly destroyed. LOG_ALWAYS_FATAL("Can't destroy the render thread"); } -void RenderThread::initializeDisplayEventReceiver() { - LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second DisplayEventReceiver?"); +void RenderThread::initializeChoreographer() { + LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second Choreographer?"); if (!Properties::isolatedProcess) { - auto receiver = std::make_unique( - ISurfaceComposer::eVsyncSourceApp, - ISurfaceComposer::eConfigChangedDispatch); - status_t status = receiver->initCheck(); - LOG_ALWAYS_FATAL_IF(status != NO_ERROR, - "Initialization of DisplayEventReceiver " - "failed with status: %d", - status); + mChoreographer = AChoreographer_create(); + LOG_ALWAYS_FATAL_IF(mChoreographer == nullptr, "Initialization of Choreographer failed"); + AChoreographer_registerRefreshRateCallback(mChoreographer, + RenderThread::refreshRateCallback, this); // Register the FD - mLooper->addFd(receiver->getFd(), 0, Looper::EVENT_INPUT, - RenderThread::displayEventReceiverCallback, this); - mVsyncSource = new DisplayEventReceiverWrapper(std::move(receiver), [this] { - DeviceInfo::get()->onDisplayConfigChanged(); - setupFrameInterval(); - }); + mLooper->addFd(AChoreographer_getFd(mChoreographer), 0, Looper::EVENT_INPUT, + RenderThread::choreographerCallback, this); + mVsyncSource = new ChoreographerSource(this); } else { mVsyncSource = new DummyVsyncSource(this); } @@ -175,7 +162,7 @@ void RenderThread::initializeDisplayEventReceiver() { void RenderThread::initThreadLocals() { setupFrameInterval(); - initializeDisplayEventReceiver(); + initializeChoreographer(); mEglManager = new EglManager(); mRenderState = new RenderState(*this); mVkManager = new VulkanManager(); @@ -183,7 +170,7 @@ void RenderThread::initThreadLocals() { } void RenderThread::setupFrameInterval() { - nsecs_t frameIntervalNanos = static_cast(1000000000 / DeviceInfo::getRefreshRate()); + nsecs_t frameIntervalNanos = DeviceInfo::getVsyncPeriod(); mTimeLord.setFrameInterval(frameIntervalNanos); mDispatchFrameDelay = static_cast(frameIntervalNanos * .25f); } @@ -288,7 +275,7 @@ void RenderThread::setGrContext(sk_sp context) { } } -int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { +int RenderThread::choreographerCallback(int fd, int events, void* data) { if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { ALOGE("Display event receiver pipe was closed or an error occurred. " "events=0x%x", @@ -302,24 +289,10 @@ int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { events); return 1; // keep the callback } + RenderThread* rt = reinterpret_cast(data); + AChoreographer_handlePendingEvents(rt->mChoreographer, data); - reinterpret_cast(data)->drainDisplayEventQueue(); - - return 1; // keep the callback -} - -void RenderThread::drainDisplayEventQueue() { - ATRACE_CALL(); - nsecs_t vsyncEvent = mVsyncSource->latestVsyncEvent(); - if (vsyncEvent > 0) { - mVsyncRequested = false; - if (mTimeLord.vsyncReceived(vsyncEvent) && !mFrameCallbackTaskPending) { - ATRACE_NAME("queue mFrameCallbackTask"); - mFrameCallbackTaskPending = true; - nsecs_t runAt = (vsyncEvent + mDispatchFrameDelay); - queue().postAt(runAt, [this]() { dispatchFrameCallbacks(); }); - } - } + return 1; } void RenderThread::dispatchFrameCallbacks() { @@ -360,7 +333,7 @@ bool RenderThread::threadLoop() { processQueue(); if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) { - drainDisplayEventQueue(); + mVsyncSource->drainPendingEvents(); mFrameCallbacks.insert(mPendingRegistrationFrameCallbacks.begin(), mPendingRegistrationFrameCallbacks.end()); mPendingRegistrationFrameCallbacks.clear(); diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index da79e97a6ceb..8be46a6d16e1 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -73,10 +74,11 @@ protected: struct VsyncSource { virtual void requestNextVsync() = 0; - virtual nsecs_t latestVsyncEvent() = 0; + virtual void drainPendingEvents() = 0; virtual ~VsyncSource() {} }; +class ChoreographerSource; class DummyVsyncSource; typedef void (*JVMAttachHook)(const char* name); @@ -136,6 +138,7 @@ private: friend class DispatchFrameCallbacks; friend class RenderProxy; friend class DummyVsyncSource; + friend class ChoreographerSource; friend class android::uirenderer::AutoBackendTextureRelease; friend class android::uirenderer::TestUtils; friend class android::uirenderer::WebViewFunctor; @@ -149,13 +152,21 @@ private: static RenderThread& getInstance(); void initThreadLocals(); - void initializeDisplayEventReceiver(); + void initializeChoreographer(); void setupFrameInterval(); - static int displayEventReceiverCallback(int fd, int events, void* data); + // Callbacks for choreographer events: + // choreographerCallback will call AChoreograper_handleEvent to call the + // corresponding callbacks for each display event type + static int choreographerCallback(int fd, int events, void* data); + // Callback that will be run on vsync ticks. + static void frameCallback(int64_t frameTimeNanos, void* data); + // Callback that will be run whenver there is a refresh rate change. + static void refreshRateCallback(int64_t vsyncPeriod, void* data); void drainDisplayEventQueue(); void dispatchFrameCallbacks(); void requestVsync(); + AChoreographer* mChoreographer; VsyncSource* mVsyncSource; bool mVsyncRequested; std::set mFrameCallbacks; -- cgit v1.2.3-59-g8ed1b From c5882c4eb614179c8dad323cbbb115b62bb35f43 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Fri, 25 Oct 2019 11:11:32 -0400 Subject: Remove dependencies on headers outside UI module This includes AndroidRuntime and core_jni_helper.h Bug: 137655431 Test: CtsUiRenderingTestCases Change-Id: If3d26f41eaf4981505ee47634097f3645fd563fd --- core/jni/LayoutlibLoader.cpp | 76 -------- libs/hwui/Android.bp | 5 + libs/hwui/DeviceInfo.cpp | 3 - libs/hwui/apex/LayoutlibLoader.cpp | 191 +++++++++++++++++++++ libs/hwui/apex/jni_runtime.cpp | 5 + libs/hwui/jni/AnimatedImageDrawable.cpp | 1 - libs/hwui/jni/Bitmap.cpp | 3 - libs/hwui/jni/BitmapFactory.cpp | 9 +- libs/hwui/jni/BitmapRegionDecoder.cpp | 4 - libs/hwui/jni/ByteBufferStreamAdaptor.cpp | 3 +- libs/hwui/jni/Camera.cpp | 3 - libs/hwui/jni/CanvasProperty.cpp | 2 - libs/hwui/jni/ColorFilter.cpp | 2 - libs/hwui/jni/CreateJavaOutputStreamAdaptor.h | 1 - libs/hwui/jni/FontFamily.cpp | 16 +- libs/hwui/jni/FontUtils.cpp | 3 +- libs/hwui/jni/Graphics.cpp | 38 +++- libs/hwui/jni/GraphicsJNI.h | 21 ++- libs/hwui/jni/GraphicsStatsService.cpp | 6 +- libs/hwui/jni/ImageDecoder.cpp | 7 +- libs/hwui/jni/Interpolator.cpp | 3 - libs/hwui/jni/MaskFilter.cpp | 4 - libs/hwui/jni/Movie.cpp | 2 - libs/hwui/jni/NinePatch.cpp | 3 - libs/hwui/jni/Paint.cpp | 2 - libs/hwui/jni/PaintFilter.cpp | 4 - libs/hwui/jni/Path.cpp | 2 - libs/hwui/jni/PathEffect.cpp | 3 - libs/hwui/jni/PathMeasure.cpp | 2 - libs/hwui/jni/Region.cpp | 3 - libs/hwui/jni/Shader.cpp | 3 - libs/hwui/jni/Typeface.cpp | 3 - libs/hwui/jni/YuvToJpegEncoder.cpp | 4 +- libs/hwui/jni/android_graphics_Canvas.cpp | 2 - libs/hwui/jni/android_graphics_ColorSpace.cpp | 13 +- .../jni/android_graphics_DisplayListCanvas.cpp | 5 - .../hwui/jni/android_graphics_HardwareRenderer.cpp | 2 - .../android_graphics_HardwareRendererObserver.cpp | 2 +- libs/hwui/jni/android_graphics_Matrix.cpp | 3 - libs/hwui/jni/android_graphics_Picture.cpp | 5 +- libs/hwui/jni/android_graphics_RenderNode.cpp | 5 - libs/hwui/jni/android_graphics_TextureLayer.cpp | 5 +- ...raphics_animation_NativeInterpolatorFactory.cpp | 6 +- ...droid_graphics_animation_RenderNodeAnimator.cpp | 6 +- ...id_graphics_drawable_AnimatedVectorDrawable.cpp | 2 - .../android_graphics_drawable_VectorDrawable.cpp | 2 - libs/hwui/jni/android_nio_utils.cpp | 2 +- libs/hwui/jni/android_util_PathParser.cpp | 2 - libs/hwui/jni/fonts/Font.cpp | 17 +- libs/hwui/jni/fonts/FontFamily.cpp | 3 +- libs/hwui/jni/graphics_jni_helpers.h | 106 ++++++++++++ libs/hwui/jni/pdf/PdfDocument.cpp | 2 - libs/hwui/jni/pdf/PdfEditor.cpp | 5 +- libs/hwui/jni/pdf/PdfRenderer.cpp | 3 - libs/hwui/jni/scoped_nullable_primitive_array.h | 103 +++++++++++ libs/hwui/jni/text/LineBreaker.cpp | 3 +- libs/hwui/jni/text/MeasuredText.cpp | 2 - ...om_android_server_input_InputManagerService.cpp | 3 - 58 files changed, 507 insertions(+), 239 deletions(-) create mode 100644 libs/hwui/apex/LayoutlibLoader.cpp create mode 100644 libs/hwui/jni/graphics_jni_helpers.h create mode 100644 libs/hwui/jni/scoped_nullable_primitive_array.h (limited to 'libs/hwui/DeviceInfo.cpp') diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp index 7ee509b4ecb4..77c1a1097240 100644 --- a/core/jni/LayoutlibLoader.cpp +++ b/core/jni/LayoutlibLoader.cpp @@ -34,19 +34,6 @@ using namespace std; 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_animation_PropertyValuesHolder(JNIEnv *env); @@ -54,25 +41,6 @@ extern int register_android_content_AssetManager(JNIEnv* env); extern int register_android_content_StringBlock(JNIEnv* env); extern int register_android_content_XmlBlock(JNIEnv* env); extern int register_android_content_res_ApkAssets(JNIEnv* env); -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_os_FileObserver(JNIEnv* env); extern int register_android_os_MessageQueue(JNIEnv* env); extern int register_android_os_SystemClock(JNIEnv* env); @@ -81,10 +49,7 @@ extern int register_android_os_Trace(JNIEnv* env); extern int register_android_text_AndroidCharacter(JNIEnv* env); extern int register_android_util_EventLog(JNIEnv* env); extern int register_android_util_Log(JNIEnv* env); -extern int register_android_util_PathParser(JNIEnv* env); extern int register_android_util_jar_StrictJarFile(JNIEnv* env); -extern int register_android_view_RenderNode(JNIEnv* env); -extern int register_android_view_DisplayListCanvas(JNIEnv* env); extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env); #define REG_JNI(name) { name } @@ -103,46 +68,6 @@ static const std::unordered_map gRegJNIMap = { #endif {"android.content.res.StringBlock", REG_JNI(register_android_content_StringBlock)}, {"android.content.res.XmlBlock", REG_JNI(register_android_content_XmlBlock)}, - {"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)}, #ifdef __linux__ {"android.os.FileObserver", REG_JNI(register_android_os_FileObserver)}, {"android.os.MessageQueue", REG_JNI(register_android_os_MessageQueue)}, @@ -153,7 +78,6 @@ static const std::unordered_map gRegJNIMap = { {"android.text.AndroidCharacter", REG_JNI(register_android_text_AndroidCharacter)}, {"android.util.EventLog", REG_JNI(register_android_util_EventLog)}, {"android.util.Log", REG_JNI(register_android_util_Log)}, - {"android.util.PathParser", REG_JNI(register_android_util_PathParser)}, {"android.util.jar.StrictJarFile", REG_JNI(register_android_util_jar_StrictJarFile)}, {"com.android.internal.util.VirtualRefBasePtr", REG_JNI(register_com_android_internal_util_VirtualRefBasePtr)}, diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 954e4daeffa7..1715a279130e 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -203,6 +203,11 @@ cc_defaults { "apex/renderthread.cpp", ], }, + host: { + srcs: [ + "apex/LayoutlibLoader.cpp", + ], + } }, } diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp index 6d4a0c6421d9..c24224cbbd67 100644 --- a/libs/hwui/DeviceInfo.cpp +++ b/libs/hwui/DeviceInfo.cpp @@ -18,9 +18,6 @@ #include #include -#include -#include - #include "Properties.h" namespace android { 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 +#include + +#include +#include +#include +#include +#include + +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 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& jniRegMap, + const vector& classesToRegister, JNIEnv* env) { + + for (const string& className : classesToRegister) { + if (jniRegMap.at(className).mProc(env) < 0) { + return -1; + } + } + return 0; +} + +static vector parseCsv(const string& csvString) { + vector result; + istringstream stream(csvString); + string segment; + while(getline(stream, segment, ',')) + { + result.push_back(segment); + } + return result; +} + +static vector parseCsv(JNIEnv* env, jstring csvJString) { + const char* charArray = env->GetStringUTFChars(csvJString, 0); + string csvString(charArray); + vector 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 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/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp index c674f9363821..a114e2f42157 100644 --- a/libs/hwui/apex/jni_runtime.cpp +++ b/libs/hwui/apex/jni_runtime.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -150,6 +151,10 @@ void init_android_graphics() { } 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 diff --git a/libs/hwui/jni/AnimatedImageDrawable.cpp b/libs/hwui/jni/AnimatedImageDrawable.cpp index 6c2a5a3f3fcc..055075d0c42a 100644 --- a/libs/hwui/jni/AnimatedImageDrawable.cpp +++ b/libs/hwui/jni/AnimatedImageDrawable.cpp @@ -17,7 +17,6 @@ #include "GraphicsJNI.h" #include "ImageDecoder.h" #include "Utils.h" -#include "core_jni_helpers.h" #include #include diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 1f2ce8ea6c81..9981e89ab561 100755 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -26,9 +26,6 @@ #include #endif -#include "core_jni_helpers.h" - -#include #include #include #include diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp index 48a5783e6464..f3395b9e6877 100644 --- a/libs/hwui/jni/BitmapFactory.cpp +++ b/libs/hwui/jni/BitmapFactory.cpp @@ -13,17 +13,15 @@ #include "SkStream.h" #include "SkUtils.h" #include "Utils.h" -#include "core_jni_helpers.h" #include #include #include #include #include +#include #include -#include #include -#include #include jfieldID gOptions_justBoundsFieldID; @@ -522,7 +520,9 @@ static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteA static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fileDescriptor, jobject padding, jobject bitmapFactoryOptions, jlong inBitmapHandle, jlong colorSpaceHandle) { - +#ifndef __ANDROID__ // LayoutLib for Windows does not support F_DUPFD_CLOEXEC + return nullObjectReturn("Not supported on Windows"); +#else NPE_CHECK_RETURN_ZERO(env, fileDescriptor); int descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor); @@ -569,6 +569,7 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi return doDecode(env, std::move(stream), padding, bitmapFactoryOptions, inBitmapHandle, colorSpaceHandle); +#endif } static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jlong native_asset, diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp index 3f80f03d7a45..712351382d97 100644 --- a/libs/hwui/jni/BitmapRegionDecoder.cpp +++ b/libs/hwui/jni/BitmapRegionDecoder.cpp @@ -28,12 +28,8 @@ #include "SkData.h" #include "SkStream.h" -#include "core_jni_helpers.h" - #include -#include #include -#include #include #include diff --git a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp index d443fd8cdf14..db5f6f6c684f 100644 --- a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp +++ b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp @@ -1,7 +1,6 @@ #include "ByteBufferStreamAdaptor.h" -#include "core_jni_helpers.h" +#include "GraphicsJNI.h" #include "Utils.h" -#include #include diff --git a/libs/hwui/jni/Camera.cpp b/libs/hwui/jni/Camera.cpp index da954972ab57..a5e1adf26861 100644 --- a/libs/hwui/jni/Camera.cpp +++ b/libs/hwui/jni/Camera.cpp @@ -1,6 +1,3 @@ -#include "jni.h" -#include "core_jni_helpers.h" - #include "SkCamera.h" #include "GraphicsJNI.h" diff --git a/libs/hwui/jni/CanvasProperty.cpp b/libs/hwui/jni/CanvasProperty.cpp index c841d6a5125a..684ee23b9fca 100644 --- a/libs/hwui/jni/CanvasProperty.cpp +++ b/libs/hwui/jni/CanvasProperty.cpp @@ -14,9 +14,7 @@ * limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include #include #include diff --git a/libs/hwui/jni/ColorFilter.cpp b/libs/hwui/jni/ColorFilter.cpp index 164d35f46a47..cef21f91f3c1 100644 --- a/libs/hwui/jni/ColorFilter.cpp +++ b/libs/hwui/jni/ColorFilter.cpp @@ -15,9 +15,7 @@ ** limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #include "SkColorFilter.h" #include "SkColorMatrixFilter.h" diff --git a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h index fccd4717c4b7..849418da01a1 100644 --- a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h +++ b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h @@ -1,7 +1,6 @@ #ifndef _ANDROID_GRAPHICS_CREATE_JAVA_OUTPUT_STREAM_ADAPTOR_H_ #define _ANDROID_GRAPHICS_CREATE_JAVA_OUTPUT_STREAM_ADAPTOR_H_ -//#include #include "jni.h" class SkMemoryStream; diff --git a/libs/hwui/jni/FontFamily.cpp b/libs/hwui/jni/FontFamily.cpp index f0cdb5e2b8c3..a2fef1e19328 100644 --- a/libs/hwui/jni/FontFamily.cpp +++ b/libs/hwui/jni/FontFamily.cpp @@ -17,9 +17,6 @@ #undef LOG_TAG #define LOG_TAG "Minikin" -#include -#include - #include "SkData.h" #include "SkFontMgr.h" #include "SkRefCnt.h" @@ -27,7 +24,6 @@ #include "GraphicsJNI.h" #include #include -#include #include "Utils.h" #include "FontUtils.h" @@ -145,15 +141,11 @@ static bool addSkTypeface(NativeFamilyBuilder* builder, sk_sp&& data, in } static void release_global_ref(const void* /*data*/, void* context) { - JNIEnv* env = AndroidRuntime::getJNIEnv(); + JNIEnv* env = GraphicsJNI::getJNIEnv(); bool needToAttach = (env == NULL); if (needToAttach) { - JavaVMAttachArgs args; - args.version = JNI_VERSION_1_4; - args.name = "release_font_data"; - args.group = NULL; - jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args); - if (result != JNI_OK) { + env = GraphicsJNI::attachJNIEnv("release_font_data"); + if (env == nullptr) { ALOGE("failed to attach to thread to release global ref."); return; } @@ -163,7 +155,7 @@ static void release_global_ref(const void* /*data*/, void* context) { env->DeleteGlobalRef(obj); if (needToAttach) { - AndroidRuntime::getJavaVM()->DetachCurrentThread(); + GraphicsJNI::detachJNIEnv(); } } diff --git a/libs/hwui/jni/FontUtils.cpp b/libs/hwui/jni/FontUtils.cpp index 0cf61b9ade89..654c5fdf6528 100644 --- a/libs/hwui/jni/FontUtils.cpp +++ b/libs/hwui/jni/FontUtils.cpp @@ -16,8 +16,7 @@ #include "FontUtils.h" -#include -#include +#include "graphics_jni_helpers.h" namespace android { namespace { diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp index 37958645f406..f76ecb4c9c8a 100644 --- a/libs/hwui/jni/Graphics.cpp +++ b/libs/hwui/jni/Graphics.cpp @@ -1,23 +1,55 @@ #undef LOG_TAG #define LOG_TAG "GraphicsJNI" +#include #include -#include #include "jni.h" #include #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #include "SkCanvas.h" #include "SkMath.h" #include "SkRegion.h" -#include #include #include using namespace android; +/*static*/ JavaVM* GraphicsJNI::mJavaVM = nullptr; + +void GraphicsJNI::setJavaVM(JavaVM* javaVM) { + mJavaVM = javaVM; +} + +/** return a pointer to the JNIEnv for this thread */ +JNIEnv* GraphicsJNI::getJNIEnv() { + assert(mJavaVM != nullptr); + JNIEnv* env; + if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + return nullptr; + } + return env; +} + +/** create a JNIEnv* for this thread or assert if one already exists */ +JNIEnv* GraphicsJNI::attachJNIEnv(const char* envName) { + assert(getJNIEnv() == nullptr); + JNIEnv* env = nullptr; + JavaVMAttachArgs args = { JNI_VERSION_1_4, envName, NULL }; + int result = mJavaVM->AttachCurrentThread(&env, (void*) &args); + if (result != JNI_OK) { + ALOGE("thread attach failed: %#x", result); + } + return env; +} + +/** detach the current thread from the JavaVM */ +void GraphicsJNI::detachJNIEnv() { + assert(mJavaVM != nullptr); + mJavaVM->DetachCurrentThread(); +} + void doThrowNPE(JNIEnv* env) { jniThrowNullPointerException(env, NULL); } diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h index 1e497654f18d..4bf3ed1c6a3e 100644 --- a/libs/hwui/jni/GraphicsJNI.h +++ b/libs/hwui/jni/GraphicsJNI.h @@ -10,10 +10,11 @@ #include "SkPoint.h" #include "SkRect.h" #include "SkColorSpace.h" -#include #include #include +#include "graphics_jni_helpers.h" + class SkBitmapRegionDecoder; class SkCanvas; @@ -39,6 +40,20 @@ public: kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig }; + static void setJavaVM(JavaVM* javaVM); + + /** returns a pointer to the JavaVM provided when we initialized the module */ + static JavaVM* getJavaVM() { return mJavaVM; } + + /** return a pointer to the JNIEnv for this thread */ + static JNIEnv* getJNIEnv(); + + /** create a JNIEnv* for this thread or assert if one already exists */ + static JNIEnv* attachJNIEnv(const char* envName); + + /** detach the current thread from the JavaVM */ + static void detachJNIEnv(); + // returns true if an exception is set (and dumps it out to the Log) static bool hasException(JNIEnv*); @@ -131,6 +146,10 @@ public: * above. */ static SkColor4f convertColorLong(jlong color); + +private: + /* JNI JavaVM pointer */ + static JavaVM* mJavaVM; }; class HeapAllocator : public SkBRDAllocator { diff --git a/libs/hwui/jni/GraphicsStatsService.cpp b/libs/hwui/jni/GraphicsStatsService.cpp index 2ce392daeb87..e9259462bcac 100644 --- a/libs/hwui/jni/GraphicsStatsService.cpp +++ b/libs/hwui/jni/GraphicsStatsService.cpp @@ -18,16 +18,14 @@ #define LOG_TAG "GraphicsStatsService" #include -#include #include -#include #include #include #include #include #include #include -#include "core_jni_helpers.h" +#include "GraphicsJNI.h" namespace android { @@ -116,7 +114,7 @@ static jobject gGraphicsStatsServiceObject = nullptr; static jmethodID gGraphicsStatsService_pullGraphicsStatsMethodID; static JNIEnv* getJNIEnv() { - JavaVM* vm = AndroidRuntime::getJavaVM(); + JavaVM* vm = GraphicsJNI::getJavaVM(); JNIEnv* env = nullptr; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { if (vm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) { diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp index e17e057d75c7..b6b378539bd0 100644 --- a/libs/hwui/jni/ImageDecoder.cpp +++ b/libs/hwui/jni/ImageDecoder.cpp @@ -22,7 +22,6 @@ #include "ImageDecoder.h" #include "NinePatchPeeker.h" #include "Utils.h" -#include "core_jni_helpers.h" #include #include @@ -34,7 +33,7 @@ #include #include -#include +#include #include using namespace android; @@ -154,6 +153,9 @@ static jobject native_create(JNIEnv* env, std::unique_ptr stream, static jobject ImageDecoder_nCreateFd(JNIEnv* env, jobject /*clazz*/, jobject fileDescriptor, jboolean preferAnimation, jobject source) { +#ifndef __ANDROID__ // LayoutLib for Windows does not support F_DUPFD_CLOEXEC + return throw_exception(env, kSourceException, "Only supported on Android", nullptr, source); +#else int descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor); struct stat fdStat; @@ -172,6 +174,7 @@ static jobject ImageDecoder_nCreateFd(JNIEnv* env, jobject /*clazz*/, std::unique_ptr fileStream(new SkFILEStream(file)); return native_create(env, std::move(fileStream), source, preferAnimation); +#endif } static jobject ImageDecoder_nCreateInputStream(JNIEnv* env, jobject /*clazz*/, diff --git a/libs/hwui/jni/Interpolator.cpp b/libs/hwui/jni/Interpolator.cpp index fa28359281db..146d634a297c 100644 --- a/libs/hwui/jni/Interpolator.cpp +++ b/libs/hwui/jni/Interpolator.cpp @@ -1,8 +1,5 @@ #include "GraphicsJNI.h" #include "SkInterpolator.h" -#include "core_jni_helpers.h" - -#include static jlong Interpolator_constructor(JNIEnv* env, jobject clazz, jint valueCount, jint frameCount) { diff --git a/libs/hwui/jni/MaskFilter.cpp b/libs/hwui/jni/MaskFilter.cpp index 33d346f5d379..5383032e0f77 100644 --- a/libs/hwui/jni/MaskFilter.cpp +++ b/libs/hwui/jni/MaskFilter.cpp @@ -4,10 +4,6 @@ #include "SkBlurMaskFilter.h" #include "SkTableMaskFilter.h" -#include "core_jni_helpers.h" - -#include - static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) { if (NULL == ptr) { doThrowIAE(env); diff --git a/libs/hwui/jni/Movie.cpp b/libs/hwui/jni/Movie.cpp index 4c10a85c8257..ede0ca8cda5b 100644 --- a/libs/hwui/jni/Movie.cpp +++ b/libs/hwui/jni/Movie.cpp @@ -6,13 +6,11 @@ #include "SkStream.h" #include "SkUtils.h" #include "Utils.h" -#include "core_jni_helpers.h" #include #include #include #include -#include #include static jclass gMovie_class; diff --git a/libs/hwui/jni/NinePatch.cpp b/libs/hwui/jni/NinePatch.cpp index 988615524cca..6942017d5f27 100644 --- a/libs/hwui/jni/NinePatch.cpp +++ b/libs/hwui/jni/NinePatch.cpp @@ -31,9 +31,6 @@ #include "NinePatchPeeker.h" #include "NinePatchUtils.h" -#include -#include "core_jni_helpers.h" - jclass gInsetStruct_class; jmethodID gInsetStruct_constructorMethodID; diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index 7dda47b30578..df8635a8fe5a 100644 --- a/libs/hwui/jni/Paint.cpp +++ b/libs/hwui/jni/Paint.cpp @@ -20,9 +20,7 @@ #include -#include "jni.h" #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #include #include #include diff --git a/libs/hwui/jni/PaintFilter.cpp b/libs/hwui/jni/PaintFilter.cpp index 4fe9140572d3..ec115b4e141c 100644 --- a/libs/hwui/jni/PaintFilter.cpp +++ b/libs/hwui/jni/PaintFilter.cpp @@ -15,11 +15,7 @@ ** limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include - -#include "core_jni_helpers.h" #include "hwui/Paint.h" #include "hwui/PaintFilter.h" diff --git a/libs/hwui/jni/Path.cpp b/libs/hwui/jni/Path.cpp index 481445258e3c..d67bcf221681 100644 --- a/libs/hwui/jni/Path.cpp +++ b/libs/hwui/jni/Path.cpp @@ -20,9 +20,7 @@ // To change this file, either edit the include, or device/tools/gluemaker/main.cpp, // or one of the auxilary file specifications in device/tools/gluemaker. -#include "jni.h" #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #include "SkPath.h" #include "SkPathOps.h" diff --git a/libs/hwui/jni/PathEffect.cpp b/libs/hwui/jni/PathEffect.cpp index a4992de72ff6..f99bef7b7d58 100644 --- a/libs/hwui/jni/PathEffect.cpp +++ b/libs/hwui/jni/PathEffect.cpp @@ -4,9 +4,6 @@ #include "SkDashPathEffect.h" #include "SkDiscretePathEffect.h" #include "SkPathEffect.h" -#include "core_jni_helpers.h" - -#include class SkPathEffectGlue { public: diff --git a/libs/hwui/jni/PathMeasure.cpp b/libs/hwui/jni/PathMeasure.cpp index 70e528d4be6f..acf893e9544c 100644 --- a/libs/hwui/jni/PathMeasure.cpp +++ b/libs/hwui/jni/PathMeasure.cpp @@ -15,9 +15,7 @@ ** limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include #include "SkPathMeasure.h" diff --git a/libs/hwui/jni/Region.cpp b/libs/hwui/jni/Region.cpp index 87662f713449..c95bcea57ef5 100644 --- a/libs/hwui/jni/Region.cpp +++ b/libs/hwui/jni/Region.cpp @@ -24,9 +24,6 @@ #include "android_os_Parcel.h" #include "android_util_Binder.h" -#include -#include - namespace android { static jfieldID gRegion_nativeInstanceFieldID; diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp index f5e2a5244416..0f6837640524 100644 --- a/libs/hwui/jni/Shader.cpp +++ b/libs/hwui/jni/Shader.cpp @@ -4,11 +4,8 @@ #include "SkImagePriv.h" #include "SkShader.h" #include "SkBlendMode.h" -#include "core_jni_helpers.h" #include "include/effects/SkRuntimeEffect.h" -#include - #include using namespace android::uirenderer; diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp index 4ce56ba7444f..2a5f402a4fa6 100644 --- a/libs/hwui/jni/Typeface.cpp +++ b/libs/hwui/jni/Typeface.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -#include "jni.h" -#include "core_jni_helpers.h" - #include "FontUtils.h" #include "GraphicsJNI.h" #include diff --git a/libs/hwui/jni/YuvToJpegEncoder.cpp b/libs/hwui/jni/YuvToJpegEncoder.cpp index 09adc824e520..689cf0bea741 100644 --- a/libs/hwui/jni/YuvToJpegEncoder.cpp +++ b/libs/hwui/jni/YuvToJpegEncoder.cpp @@ -4,9 +4,7 @@ #include #include -#include "core_jni_helpers.h" - -#include +#include "graphics_jni_helpers.h" YuvToJpegEncoder* YuvToJpegEncoder::create(int format, int* strides) { // Only ImageFormat.NV21 and ImageFormat.YUY2 are supported diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp index 0ad3339ee05f..4aff3e544efa 100644 --- a/libs/hwui/jni/android_graphics_Canvas.cpp +++ b/libs/hwui/jni/android_graphics_Canvas.cpp @@ -14,9 +14,7 @@ * limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #ifdef __ANDROID_ #include diff --git a/libs/hwui/jni/android_graphics_ColorSpace.cpp b/libs/hwui/jni/android_graphics_ColorSpace.cpp index 7648fd021d18..232fd71a12b4 100644 --- a/libs/hwui/jni/android_graphics_ColorSpace.cpp +++ b/libs/hwui/jni/android_graphics_ColorSpace.cpp @@ -14,12 +14,11 @@ * limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #include "SkColor.h" #include "SkColorSpace.h" +#include "SkHalf.h" using namespace android; @@ -42,9 +41,13 @@ static skcms_Matrix3x3 getNativeXYZMatrix(JNIEnv* env, jfloatArray xyzD50) { /////////////////////////////////////////////////////////////////////////////// static float halfToFloat(uint16_t bits) { - __fp16 h; - memcpy(&h, &bits, 2); - return (float)h; +#ifdef __ANDROID__ // __fp16 is not defined on non-Android builds + __fp16 h; + memcpy(&h, &bits, 2); + return (float)h; +#else + return SkHalfToFloat(bits); +#endif } SkColor4f GraphicsJNI::convertColorLong(jlong color) { diff --git a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp index ca10c1e6561b..54822f1f07e2 100644 --- a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp +++ b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp @@ -14,11 +14,8 @@ * limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include -#include #ifdef __ANDROID__ // Layoutlib does not support Looper and device properties #include #endif @@ -36,8 +33,6 @@ #include #endif -#include "core_jni_helpers.h" - namespace android { using namespace uirenderer; diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index 76bfce8ab5d7..49c7fcd468e1 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -44,8 +44,6 @@ #include #include "android_graphics_HardwareRendererObserver.h" -#include "core_jni_helpers.h" -#include "jni.h" namespace android { diff --git a/libs/hwui/jni/android_graphics_HardwareRendererObserver.cpp b/libs/hwui/jni/android_graphics_HardwareRendererObserver.cpp index 89b77b0b069a..5b3e65648981 100644 --- a/libs/hwui/jni/android_graphics_HardwareRendererObserver.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRendererObserver.cpp @@ -16,7 +16,7 @@ #include "android_graphics_HardwareRendererObserver.h" -#include "core_jni_helpers.h" +#include "graphics_jni_helpers.h" #include "nativehelper/jni_macros.h" #include diff --git a/libs/hwui/jni/android_graphics_Matrix.cpp b/libs/hwui/jni/android_graphics_Matrix.cpp index 13369763e0cf..7338ef24cb58 100644 --- a/libs/hwui/jni/android_graphics_Matrix.cpp +++ b/libs/hwui/jni/android_graphics_Matrix.cpp @@ -18,9 +18,6 @@ #include "GraphicsJNI.h" #include "Matrix.h" #include "SkMatrix.h" -#include "core_jni_helpers.h" - -#include namespace android { diff --git a/libs/hwui/jni/android_graphics_Picture.cpp b/libs/hwui/jni/android_graphics_Picture.cpp index 1d085e5ccc49..403efb2ab9c9 100644 --- a/libs/hwui/jni/android_graphics_Picture.cpp +++ b/libs/hwui/jni/android_graphics_Picture.cpp @@ -19,12 +19,9 @@ #include "Picture.h" #include "SkCanvas.h" #include "SkStream.h" -#include "core_jni_helpers.h" -#include "nativehelper/jni_macros.h" - -#include #include +#include "nativehelper/jni_macros.h" namespace android { diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp index a5b9e5e6a28e..85c802b40459 100644 --- a/libs/hwui/jni/android_graphics_RenderNode.cpp +++ b/libs/hwui/jni/android_graphics_RenderNode.cpp @@ -15,10 +15,7 @@ */ #define ATRACE_TAG ATRACE_TAG_VIEW -#include "jni.h" #include "GraphicsJNI.h" -#include -#include #include #include @@ -31,8 +28,6 @@ #include #include -#include "core_jni_helpers.h" - namespace android { using namespace uirenderer; diff --git a/libs/hwui/jni/android_graphics_TextureLayer.cpp b/libs/hwui/jni/android_graphics_TextureLayer.cpp index e8043d2438bd..bd20269d3751 100644 --- a/libs/hwui/jni/android_graphics_TextureLayer.cpp +++ b/libs/hwui/jni/android_graphics_TextureLayer.cpp @@ -14,11 +14,8 @@ * limitations under the License. */ -#include "jni.h" -#include - #include -#include "core_jni_helpers.h" +#include "graphics_jni_helpers.h" #include #include diff --git a/libs/hwui/jni/android_graphics_animation_NativeInterpolatorFactory.cpp b/libs/hwui/jni/android_graphics_animation_NativeInterpolatorFactory.cpp index 2073ac2d24be..764eff9a04be 100644 --- a/libs/hwui/jni/android_graphics_animation_NativeInterpolatorFactory.cpp +++ b/libs/hwui/jni/android_graphics_animation_NativeInterpolatorFactory.cpp @@ -16,12 +16,10 @@ #define LOG_TAG "OpenGLRenderer" -#include "jni.h" -#include +#include #include -#include "core_jni_helpers.h" -#include +#include "graphics_jni_helpers.h" namespace android { diff --git a/libs/hwui/jni/android_graphics_animation_RenderNodeAnimator.cpp b/libs/hwui/jni/android_graphics_animation_RenderNodeAnimator.cpp index 878d4fc13f6d..c6d26f853c1d 100644 --- a/libs/hwui/jni/android_graphics_animation_RenderNodeAnimator.cpp +++ b/libs/hwui/jni/android_graphics_animation_RenderNodeAnimator.cpp @@ -16,15 +16,11 @@ #define LOG_TAG "OpenGLRenderer" -#include "jni.h" -#include -#include - #include #include #include -#include "core_jni_helpers.h" +#include "graphics_jni_helpers.h" namespace android { diff --git a/libs/hwui/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp b/libs/hwui/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp index 12465566eceb..b3121e7b0373 100644 --- a/libs/hwui/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp +++ b/libs/hwui/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp @@ -16,9 +16,7 @@ #include "android/log.h" -#include "jni.h" #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #include "Animator.h" #include "Interpolator.h" diff --git a/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp b/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp index 58a2379a6999..8a262969614e 100644 --- a/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp +++ b/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp @@ -15,8 +15,6 @@ */ #include "GraphicsJNI.h" -#include "jni.h" -#include "core_jni_helpers.h" #include "PathParser.h" #include "VectorDrawable.h" diff --git a/libs/hwui/jni/android_nio_utils.cpp b/libs/hwui/jni/android_nio_utils.cpp index 1e6d49e49b72..c2b09c1d15d7 100644 --- a/libs/hwui/jni/android_nio_utils.cpp +++ b/libs/hwui/jni/android_nio_utils.cpp @@ -16,7 +16,7 @@ #include "android_nio_utils.h" -#include "core_jni_helpers.h" +#include namespace android { diff --git a/libs/hwui/jni/android_util_PathParser.cpp b/libs/hwui/jni/android_util_PathParser.cpp index 10efb95100ac..df5e9cd44ed0 100644 --- a/libs/hwui/jni/android_util_PathParser.cpp +++ b/libs/hwui/jni/android_util_PathParser.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" #include @@ -22,7 +21,6 @@ #include #include -#include "core_jni_helpers.h" namespace android { diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp index d53883298f5b..5714cd1d0390 100644 --- a/libs/hwui/jni/fonts/Font.cpp +++ b/libs/hwui/jni/fonts/Font.cpp @@ -17,16 +17,12 @@ #undef LOG_TAG #define LOG_TAG "Minikin" -#include -#include - #include "SkData.h" #include "SkFontMgr.h" #include "SkRefCnt.h" #include "SkTypeface.h" #include "GraphicsJNI.h" #include -#include #include "Utils.h" #include "FontUtils.h" @@ -52,14 +48,11 @@ static void releaseFont(jlong font) { } static void release_global_ref(const void* /*data*/, void* context) { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (env == nullptr) { - JavaVMAttachArgs args; - args.version = JNI_VERSION_1_4; - args.name = "release_font_data"; - args.group = nullptr; - jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args); - if (result != JNI_OK) { + JNIEnv* env = GraphicsJNI::getJNIEnv(); + bool needToAttach = (env == nullptr); + if (needToAttach) { + env = GraphicsJNI::attachJNIEnv("release_font_data"); + if (env == nullptr) { ALOGE("failed to attach to thread to release global ref."); return; } diff --git a/libs/hwui/jni/fonts/FontFamily.cpp b/libs/hwui/jni/fonts/FontFamily.cpp index 26d70a0a2c9c..df619d9f1406 100644 --- a/libs/hwui/jni/fonts/FontFamily.cpp +++ b/libs/hwui/jni/fonts/FontFamily.cpp @@ -17,9 +17,8 @@ #undef LOG_TAG #define LOG_TAG "Minikin" -#include +#include "graphics_jni_helpers.h" #include -#include #include "FontUtils.h" diff --git a/libs/hwui/jni/graphics_jni_helpers.h b/libs/hwui/jni/graphics_jni_helpers.h new file mode 100644 index 000000000000..b97cc6a10179 --- /dev/null +++ b/libs/hwui/jni/graphics_jni_helpers.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRAPHICS_JNI_HELPERS +#define GRAPHICS_JNI_HELPERS + +#include +#include +#include +#include +#include + +// Host targets (layoutlib) do not differentiate between regular and critical native methods, +// and they need all the JNI methods to have JNIEnv* and jclass/jobject as their first two arguments. +// The following macro allows to have those arguments when compiling for host while omitting them when +// compiling for Android. +#ifdef __ANDROID__ +#define CRITICAL_JNI_PARAMS +#define CRITICAL_JNI_PARAMS_COMMA +#else +#define CRITICAL_JNI_PARAMS JNIEnv*, jclass +#define CRITICAL_JNI_PARAMS_COMMA JNIEnv*, jclass, +#endif + +namespace android { + +// Defines some helpful functions. + +static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) { + jclass clazz = env->FindClass(class_name); + LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name); + return clazz; +} + +static inline jfieldID GetFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name, + const char* field_signature) { + jfieldID res = env->GetFieldID(clazz, field_name, field_signature); + LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name); + return res; +} + +static inline jmethodID GetMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name, + const char* method_signature) { + jmethodID res = env->GetMethodID(clazz, method_name, method_signature); + LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s", method_name); + return res; +} + +static inline jfieldID GetStaticFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name, + const char* field_signature) { + jfieldID res = env->GetStaticFieldID(clazz, field_name, field_signature); + LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name); + return res; +} + +static inline jmethodID GetStaticMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name, + const char* method_signature) { + jmethodID res = env->GetStaticMethodID(clazz, method_name, method_signature); + LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static method %s", method_name); + return res; +} + +template +static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) { + jobject res = env->NewGlobalRef(in); + LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference."); + return static_cast(res); +} + +static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className, + const JNINativeMethod* gMethods, int numMethods) { + int res = jniRegisterNativeMethods(env, className, gMethods, numMethods); + LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods."); + return res; +} + +/** + * Read the specified field from jobject, and convert to std::string. + * If the field cannot be obtained, return defaultValue. + */ +static inline std::string getStringField(JNIEnv* env, jobject obj, jfieldID fieldId, + const char* defaultValue) { + ScopedLocalRef strObj(env, jstring(env->GetObjectField(obj, fieldId))); + if (strObj != nullptr) { + ScopedUtfChars chars(env, strObj.get()); + return std::string(chars.c_str()); + } + return std::string(defaultValue); +} + +} // namespace android + +#endif // GRAPHICS_JNI_HELPERS diff --git a/libs/hwui/jni/pdf/PdfDocument.cpp b/libs/hwui/jni/pdf/PdfDocument.cpp index 5f67d3008f45..d21eb3f6a208 100644 --- a/libs/hwui/jni/pdf/PdfDocument.cpp +++ b/libs/hwui/jni/pdf/PdfDocument.cpp @@ -14,9 +14,7 @@ * limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" -#include "core_jni_helpers.h" #include #include "CreateJavaOutputStreamAdaptor.h" diff --git a/libs/hwui/jni/pdf/PdfEditor.cpp b/libs/hwui/jni/pdf/PdfEditor.cpp index 545f4c521ae8..828d6e3992b6 100644 --- a/libs/hwui/jni/pdf/PdfEditor.cpp +++ b/libs/hwui/jni/pdf/PdfEditor.cpp @@ -27,8 +27,7 @@ #include "PdfUtils.h" -#include "jni.h" -#include +#include "graphics_jni_helpers.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" @@ -40,8 +39,6 @@ #include "SkMatrix.h" -#include - namespace android { enum PageBox {PAGE_BOX_MEDIA, PAGE_BOX_CROP}; diff --git a/libs/hwui/jni/pdf/PdfRenderer.cpp b/libs/hwui/jni/pdf/PdfRenderer.cpp index 761830b0e97c..cc1f96197c74 100644 --- a/libs/hwui/jni/pdf/PdfRenderer.cpp +++ b/libs/hwui/jni/pdf/PdfRenderer.cpp @@ -16,14 +16,11 @@ #include "PdfUtils.h" -#include "jni.h" -#include #include "GraphicsJNI.h" #include "SkBitmap.h" #include "SkMatrix.h" #include "fpdfview.h" -#include "core_jni_helpers.h" #include #include #include diff --git a/libs/hwui/jni/scoped_nullable_primitive_array.h b/libs/hwui/jni/scoped_nullable_primitive_array.h new file mode 100644 index 000000000000..77f4c9d14f07 --- /dev/null +++ b/libs/hwui/jni/scoped_nullable_primitive_array.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2017 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 SCOPED_NULLABLE_PRIMITIVE_ARRAY_H +#define SCOPED_NULLABLE_PRIMITIVE_ARRAY_H + +#include + +namespace android { + +#define ARRAY_TRAITS(ARRAY_TYPE, POINTER_TYPE, NAME) \ +class NAME ## ArrayTraits { \ +public: \ + static constexpr void getArrayRegion(JNIEnv* env, ARRAY_TYPE array, size_t start, \ + size_t len, POINTER_TYPE out) { \ + env->Get ## NAME ## ArrayRegion(array, start, len, out); \ + } \ + \ + static constexpr POINTER_TYPE getArrayElements(JNIEnv* env, ARRAY_TYPE array) { \ + return env->Get ## NAME ## ArrayElements(array, nullptr); \ + } \ + \ + static constexpr void releaseArrayElements(JNIEnv* env, ARRAY_TYPE array, \ + POINTER_TYPE buffer, jint mode) { \ + env->Release ## NAME ## ArrayElements(array, buffer, mode); \ + } \ +}; \ + +ARRAY_TRAITS(jbooleanArray, jboolean*, Boolean) +ARRAY_TRAITS(jbyteArray, jbyte*, Byte) +ARRAY_TRAITS(jcharArray, jchar*, Char) +ARRAY_TRAITS(jdoubleArray, jdouble*, Double) +ARRAY_TRAITS(jfloatArray, jfloat*, Float) +ARRAY_TRAITS(jintArray, jint*, Int) +ARRAY_TRAITS(jlongArray, jlong*, Long) +ARRAY_TRAITS(jshortArray, jshort*, Short) + +#undef ARRAY_TRAITS + +template +class ScopedArrayRO { +public: + ScopedArrayRO(JNIEnv* env, JavaArrayType javaArray) : mEnv(env), mJavaArray(javaArray) { + if (mJavaArray == nullptr) { + mSize = 0; + mRawArray = nullptr; + } else { + mSize = mEnv->GetArrayLength(mJavaArray); + if (mSize <= preallocSize) { + Traits::getArrayRegion(mEnv, mJavaArray, 0, mSize, mBuffer); + mRawArray = mBuffer; + } else { + mRawArray = Traits::getArrayElements(mEnv, mJavaArray); + } + } + } + + ~ScopedArrayRO() { + if (mRawArray != nullptr && mRawArray != mBuffer) { + Traits::releaseArrayElements(mEnv, mJavaArray, mRawArray, JNI_ABORT); + } + } + + const PrimitiveType* get() const { return mRawArray; } + const PrimitiveType& operator[](size_t n) const { return mRawArray[n]; } + size_t size() const { return mSize; } + +private: + JNIEnv* const mEnv; + JavaArrayType mJavaArray; + PrimitiveType* mRawArray; + size_t mSize; + PrimitiveType mBuffer[preallocSize]; + DISALLOW_COPY_AND_ASSIGN(ScopedArrayRO); +}; + +// ScopedNullable***ArrayRO provide convenient read-only access to Java array from JNI code. +// These accept nullptr. In that case, get() returns nullptr and size() returns 0. +using ScopedNullableBooleanArrayRO = ScopedArrayRO; +using ScopedNullableByteArrayRO = ScopedArrayRO; +using ScopedNullableCharArrayRO = ScopedArrayRO; +using ScopedNullableDoubleArrayRO = ScopedArrayRO; +using ScopedNullableFloatArrayRO = ScopedArrayRO; +using ScopedNullableIntArrayRO = ScopedArrayRO; +using ScopedNullableLongArrayRO = ScopedArrayRO; +using ScopedNullableShortArrayRO = ScopedArrayRO; + +} // namespace android + +#endif // SCOPED_NULLABLE_PRIMITIVE_ARRAY_H diff --git a/libs/hwui/jni/text/LineBreaker.cpp b/libs/hwui/jni/text/LineBreaker.cpp index 02963d8d6072..69865171a09d 100644 --- a/libs/hwui/jni/text/LineBreaker.cpp +++ b/libs/hwui/jni/text/LineBreaker.cpp @@ -19,10 +19,9 @@ #include "utils/misc.h" #include "utils/Log.h" +#include "graphics_jni_helpers.h" #include #include -#include -#include "core_jni_helpers.h" #include "scoped_nullable_primitive_array.h" #include #include diff --git a/libs/hwui/jni/text/MeasuredText.cpp b/libs/hwui/jni/text/MeasuredText.cpp index e001bd44dc78..7793746ee285 100644 --- a/libs/hwui/jni/text/MeasuredText.cpp +++ b/libs/hwui/jni/text/MeasuredText.cpp @@ -22,8 +22,6 @@ #include "utils/Log.h" #include #include -#include -#include "core_jni_helpers.h" #include #include #include diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 8772edd73845..e0d40452590b 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -27,8 +27,6 @@ #define DEBUG_INPUT_DISPATCHER_POLICY 0 -#include -#include "jni.h" #include #include #include @@ -50,7 +48,6 @@ #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b