Loading core/jni/android_view_DisplayListCanvas.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,11 @@ static void android_view_DisplayListCanvas_drawCircleProps(jlong canvasPtr, canvas->drawCircle(xProp, yProp, radiusProp, paintProp); } static void android_view_DisplayListCanvas_drawWebViewFunctor(jlong canvasPtr, jint functor) { Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr); canvas->drawWebViewFunctor(functor); } // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- Loading @@ -192,6 +197,7 @@ static JNINativeMethod gMethods[] = { { "nDrawTextureLayer", "(JJ)V", (void*) android_view_DisplayListCanvas_drawTextureLayer }, { "nDrawCircle", "(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps }, { "nDrawRoundRect", "(JJJJJJJJ)V",(void*) android_view_DisplayListCanvas_drawRoundRectProps }, { "nDrawWebViewFunctor", "(JI)V", (void*) android_view_DisplayListCanvas_drawWebViewFunctor }, }; int register_android_view_DisplayListCanvas(JNIEnv* env) { Loading graphics/java/android/graphics/RecordingCanvas.java +10 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,14 @@ public final class RecordingCanvas extends DisplayListCanvas { nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback); } /** * Calls the provided functor that was created via WebViewFunctor_create() * @hide */ public void drawWebViewFunctor(int functor) { nDrawWebViewFunctor(mNativeCanvasWrapper, functor); } /////////////////////////////////////////////////////////////////////////// // Display list /////////////////////////////////////////////////////////////////////////// Loading Loading @@ -303,4 +311,6 @@ public final class RecordingCanvas extends DisplayListCanvas { @CriticalNative private static native void nDrawRoundRect(long renderer, long propLeft, long propTop, long propRight, long propBottom, long propRx, long propRy, long propPaint); @CriticalNative private static native void nDrawWebViewFunctor(long canvas, int functor); } libs/hwui/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ cc_defaults { "hwui_lto", ], cpp_std: "experimental", cflags: [ "-DEGL_EGLEXT_PROTOTYPES", "-DGL_GLEXT_PROTOTYPES", Loading Loading @@ -226,6 +228,7 @@ cc_defaults { "RenderProperties.cpp", "SkiaCanvas.cpp", "TreeInfo.cpp", "WebViewFunctorManager.cpp", "VectorDrawable.cpp", "protos/graphicsstats.proto", ], Loading Loading @@ -330,6 +333,7 @@ cc_test { "tests/unit/TypefaceTests.cpp", "tests/unit/VectorDrawableTests.cpp", "tests/unit/VectorDrawableAtlasTests.cpp", "tests/unit/WebViewFunctorManagerTests.cpp", ], } Loading libs/hwui/RenderNode.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -288,7 +288,10 @@ void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) { mDisplayList = mStagingDisplayList; mStagingDisplayList = nullptr; if (mDisplayList) { mDisplayList->syncContents(); WebViewSyncData syncData { .applyForceDark = info && !info->disableForceDark }; mDisplayList->syncContents(syncData); handleForceDark(info); } } Loading libs/hwui/WebViewFunctorManager.cpp 0 → 100644 +167 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 "WebViewFunctorManager.h" #include <private/hwui/WebViewFunctor.h> #include "Properties.h" #include <log/log.h> #include <utils/Trace.h> #include <atomic> namespace android::uirenderer { RenderMode WebViewFunctor_queryPlatformRenderMode() { auto pipelineType = Properties::getRenderPipelineType(); switch (pipelineType) { case RenderPipelineType::SkiaGL: return RenderMode::OpenGL_ES; case RenderPipelineType::SkiaVulkan: return RenderMode::Vulkan; default: LOG_ALWAYS_FATAL("Unknown render pipeline type: %d", (int)pipelineType); } } int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode) { if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) { ALOGW("Unknown rendermode %d", (int)functorMode); return -1; } if (functorMode == RenderMode::Vulkan && WebViewFunctor_queryPlatformRenderMode() != RenderMode::Vulkan) { ALOGW("Unable to map from GLES platform to a vulkan functor"); return -1; } return WebViewFunctorManager::instance().createFunctor(prototype, functorMode); } void WebViewFunctor_release(int functor) { WebViewFunctorManager::instance().releaseFunctor(functor); } static std::atomic_int sNextId{1}; WebViewFunctor::WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { mFunctor = sNextId++; mCallbacks = callbacks; mMode = functorMode; } WebViewFunctor::~WebViewFunctor() { destroyContext(); ATRACE_NAME("WebViewFunctor::onDestroy"); mCallbacks.onDestroyed(mFunctor); } void WebViewFunctor::sync(const WebViewSyncData& syncData) const { ATRACE_NAME("WebViewFunctor::sync"); mCallbacks.onSync(mFunctor, syncData); } void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { ATRACE_NAME("WebViewFunctor::drawGl"); if (!mHasContext) { mHasContext = true; } mCallbacks.gles.draw(mFunctor, drawInfo); } void WebViewFunctor::destroyContext() { if (mHasContext) { mHasContext = false; ATRACE_NAME("WebViewFunctor::onContextDestroyed"); mCallbacks.onContextDestroyed(mFunctor); } } WebViewFunctorManager& WebViewFunctorManager::instance() { static WebViewFunctorManager sInstance; return sInstance; } int WebViewFunctorManager::createFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { auto object = std::make_unique<WebViewFunctor>(callbacks, functorMode); int id = object->id(); auto handle = object->createHandle(); { std::lock_guard _lock{mLock}; mActiveFunctors.push_back(std::move(handle)); mFunctors.push_back(std::move(object)); } return id; } void WebViewFunctorManager::releaseFunctor(int functor) { sp<WebViewFunctor::Handle> toRelease; { std::lock_guard _lock{mLock}; for (auto iter = mActiveFunctors.begin(); iter != mActiveFunctors.end(); iter++) { if ((*iter)->id() == functor) { toRelease = std::move(*iter); mActiveFunctors.erase(iter); break; } } } } void WebViewFunctorManager::onContextDestroyed() { // WARNING: SKETCHY // Because we know that we always remove from mFunctors on RenderThread, the same // thread that always invokes onContextDestroyed, we know that the functor pointers // will remain valid without the lock held. // However, we won't block new functors from being added in the meantime. mLock.lock(); const size_t size = mFunctors.size(); WebViewFunctor* toDestroyContext[size]; for (size_t i = 0; i < size; i++) { toDestroyContext[i] = mFunctors[i].get(); } mLock.unlock(); for (size_t i = 0; i < size; i++) { toDestroyContext[i]->destroyContext(); } } void WebViewFunctorManager::destroyFunctor(int functor) { std::unique_ptr<WebViewFunctor> toRelease; { std::lock_guard _lock{mLock}; for (auto iter = mFunctors.begin(); iter != mFunctors.end(); iter++) { if ((*iter)->id() == functor) { toRelease = std::move(*iter); mFunctors.erase(iter); break; } } } } sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) { std::lock_guard _lock{mLock}; for (auto& iter : mActiveFunctors) { if (iter->id() == functor) { return iter; } } return nullptr; } } // namespace android::uirenderer No newline at end of file Loading
core/jni/android_view_DisplayListCanvas.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,11 @@ static void android_view_DisplayListCanvas_drawCircleProps(jlong canvasPtr, canvas->drawCircle(xProp, yProp, radiusProp, paintProp); } static void android_view_DisplayListCanvas_drawWebViewFunctor(jlong canvasPtr, jint functor) { Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr); canvas->drawWebViewFunctor(functor); } // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- Loading @@ -192,6 +197,7 @@ static JNINativeMethod gMethods[] = { { "nDrawTextureLayer", "(JJ)V", (void*) android_view_DisplayListCanvas_drawTextureLayer }, { "nDrawCircle", "(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps }, { "nDrawRoundRect", "(JJJJJJJJ)V",(void*) android_view_DisplayListCanvas_drawRoundRectProps }, { "nDrawWebViewFunctor", "(JI)V", (void*) android_view_DisplayListCanvas_drawWebViewFunctor }, }; int register_android_view_DisplayListCanvas(JNIEnv* env) { Loading
graphics/java/android/graphics/RecordingCanvas.java +10 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,14 @@ public final class RecordingCanvas extends DisplayListCanvas { nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback); } /** * Calls the provided functor that was created via WebViewFunctor_create() * @hide */ public void drawWebViewFunctor(int functor) { nDrawWebViewFunctor(mNativeCanvasWrapper, functor); } /////////////////////////////////////////////////////////////////////////// // Display list /////////////////////////////////////////////////////////////////////////// Loading Loading @@ -303,4 +311,6 @@ public final class RecordingCanvas extends DisplayListCanvas { @CriticalNative private static native void nDrawRoundRect(long renderer, long propLeft, long propTop, long propRight, long propBottom, long propRx, long propRy, long propPaint); @CriticalNative private static native void nDrawWebViewFunctor(long canvas, int functor); }
libs/hwui/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ cc_defaults { "hwui_lto", ], cpp_std: "experimental", cflags: [ "-DEGL_EGLEXT_PROTOTYPES", "-DGL_GLEXT_PROTOTYPES", Loading Loading @@ -226,6 +228,7 @@ cc_defaults { "RenderProperties.cpp", "SkiaCanvas.cpp", "TreeInfo.cpp", "WebViewFunctorManager.cpp", "VectorDrawable.cpp", "protos/graphicsstats.proto", ], Loading Loading @@ -330,6 +333,7 @@ cc_test { "tests/unit/TypefaceTests.cpp", "tests/unit/VectorDrawableTests.cpp", "tests/unit/VectorDrawableAtlasTests.cpp", "tests/unit/WebViewFunctorManagerTests.cpp", ], } Loading
libs/hwui/RenderNode.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -288,7 +288,10 @@ void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) { mDisplayList = mStagingDisplayList; mStagingDisplayList = nullptr; if (mDisplayList) { mDisplayList->syncContents(); WebViewSyncData syncData { .applyForceDark = info && !info->disableForceDark }; mDisplayList->syncContents(syncData); handleForceDark(info); } } Loading
libs/hwui/WebViewFunctorManager.cpp 0 → 100644 +167 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 "WebViewFunctorManager.h" #include <private/hwui/WebViewFunctor.h> #include "Properties.h" #include <log/log.h> #include <utils/Trace.h> #include <atomic> namespace android::uirenderer { RenderMode WebViewFunctor_queryPlatformRenderMode() { auto pipelineType = Properties::getRenderPipelineType(); switch (pipelineType) { case RenderPipelineType::SkiaGL: return RenderMode::OpenGL_ES; case RenderPipelineType::SkiaVulkan: return RenderMode::Vulkan; default: LOG_ALWAYS_FATAL("Unknown render pipeline type: %d", (int)pipelineType); } } int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode) { if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) { ALOGW("Unknown rendermode %d", (int)functorMode); return -1; } if (functorMode == RenderMode::Vulkan && WebViewFunctor_queryPlatformRenderMode() != RenderMode::Vulkan) { ALOGW("Unable to map from GLES platform to a vulkan functor"); return -1; } return WebViewFunctorManager::instance().createFunctor(prototype, functorMode); } void WebViewFunctor_release(int functor) { WebViewFunctorManager::instance().releaseFunctor(functor); } static std::atomic_int sNextId{1}; WebViewFunctor::WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { mFunctor = sNextId++; mCallbacks = callbacks; mMode = functorMode; } WebViewFunctor::~WebViewFunctor() { destroyContext(); ATRACE_NAME("WebViewFunctor::onDestroy"); mCallbacks.onDestroyed(mFunctor); } void WebViewFunctor::sync(const WebViewSyncData& syncData) const { ATRACE_NAME("WebViewFunctor::sync"); mCallbacks.onSync(mFunctor, syncData); } void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { ATRACE_NAME("WebViewFunctor::drawGl"); if (!mHasContext) { mHasContext = true; } mCallbacks.gles.draw(mFunctor, drawInfo); } void WebViewFunctor::destroyContext() { if (mHasContext) { mHasContext = false; ATRACE_NAME("WebViewFunctor::onContextDestroyed"); mCallbacks.onContextDestroyed(mFunctor); } } WebViewFunctorManager& WebViewFunctorManager::instance() { static WebViewFunctorManager sInstance; return sInstance; } int WebViewFunctorManager::createFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { auto object = std::make_unique<WebViewFunctor>(callbacks, functorMode); int id = object->id(); auto handle = object->createHandle(); { std::lock_guard _lock{mLock}; mActiveFunctors.push_back(std::move(handle)); mFunctors.push_back(std::move(object)); } return id; } void WebViewFunctorManager::releaseFunctor(int functor) { sp<WebViewFunctor::Handle> toRelease; { std::lock_guard _lock{mLock}; for (auto iter = mActiveFunctors.begin(); iter != mActiveFunctors.end(); iter++) { if ((*iter)->id() == functor) { toRelease = std::move(*iter); mActiveFunctors.erase(iter); break; } } } } void WebViewFunctorManager::onContextDestroyed() { // WARNING: SKETCHY // Because we know that we always remove from mFunctors on RenderThread, the same // thread that always invokes onContextDestroyed, we know that the functor pointers // will remain valid without the lock held. // However, we won't block new functors from being added in the meantime. mLock.lock(); const size_t size = mFunctors.size(); WebViewFunctor* toDestroyContext[size]; for (size_t i = 0; i < size; i++) { toDestroyContext[i] = mFunctors[i].get(); } mLock.unlock(); for (size_t i = 0; i < size; i++) { toDestroyContext[i]->destroyContext(); } } void WebViewFunctorManager::destroyFunctor(int functor) { std::unique_ptr<WebViewFunctor> toRelease; { std::lock_guard _lock{mLock}; for (auto iter = mFunctors.begin(); iter != mFunctors.end(); iter++) { if ((*iter)->id() == functor) { toRelease = std::move(*iter); mFunctors.erase(iter); break; } } } } sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) { std::lock_guard _lock{mLock}; for (auto& iter : mActiveFunctors) { if (iter->id() == functor) { return iter; } } return nullptr; } } // namespace android::uirenderer No newline at end of file