Use CPU rendering for host builds
This bypasses the computation of PipelineRenderType on host to force
using the CPU rendering pipeline.
Bug: 322360037
Test: build libhwui on host
Change-Id: Icb5178ba04e5348868c6c7f637e0c7a341fc84cd
diff --git a/libs/hostgraphics/ANativeWindow.cpp b/libs/hostgraphics/ANativeWindow.cpp
new file mode 100644
index 0000000..fcfaf02
--- /dev/null
+++ b/libs/hostgraphics/ANativeWindow.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2024 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 <system/window.h>
+
+static int32_t query(ANativeWindow* window, int what) {
+ int value;
+ int res = window->query(window, what, &value);
+ return res < 0 ? res : value;
+}
+
+static int64_t query64(ANativeWindow* window, int what) {
+ int64_t value;
+ int res = window->perform(window, what, &value);
+ return res < 0 ? res : value;
+}
+
+int ANativeWindow_setCancelBufferInterceptor(ANativeWindow* window,
+ ANativeWindow_cancelBufferInterceptor interceptor,
+ void* data) {
+ return window->perform(window, NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR, interceptor, data);
+}
+
+int ANativeWindow_setDequeueBufferInterceptor(ANativeWindow* window,
+ ANativeWindow_dequeueBufferInterceptor interceptor,
+ void* data) {
+ return window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR, interceptor, data);
+}
+
+int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window,
+ ANativeWindow_queueBufferInterceptor interceptor,
+ void* data) {
+ return window->perform(window, NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR, interceptor, data);
+}
+
+int ANativeWindow_setPerformInterceptor(ANativeWindow* window,
+ ANativeWindow_performInterceptor interceptor, void* data) {
+ return window->perform(window, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR, interceptor, data);
+}
+
+int ANativeWindow_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) {
+ return window->dequeueBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
+ return window->cancelBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout) {
+ return window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, timeout);
+}
+
+// extern "C", so that it can be used outside libhostgraphics (in host hwui/.../CanvasContext.cpp)
+extern "C" void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) {
+ if (!window || !query(window, NATIVE_WINDOW_IS_VALID)) {
+ return;
+ }
+ window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS);
+}
+
+int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window) {
+ return query64(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_START);
+}
+
+int64_t ANativeWindow_getLastDequeueDuration(ANativeWindow* window) {
+ return query64(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION);
+}
+
+int64_t ANativeWindow_getLastQueueDuration(ANativeWindow* window) {
+ return query64(window, NATIVE_WINDOW_GET_LAST_QUEUE_DURATION);
+}
+
+int32_t ANativeWindow_getWidth(ANativeWindow* window) {
+ return query(window, NATIVE_WINDOW_WIDTH);
+}
+
+int32_t ANativeWindow_getHeight(ANativeWindow* window) {
+ return query(window, NATIVE_WINDOW_HEIGHT);
+}
+
+int32_t ANativeWindow_getFormat(ANativeWindow* window) {
+ return query(window, NATIVE_WINDOW_FORMAT);
+}
+
+void ANativeWindow_acquire(ANativeWindow* window) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ window->incStrong((void*)ANativeWindow_acquire);
+}
+
+void ANativeWindow_release(ANativeWindow* window) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ window->decStrong((void*)ANativeWindow_acquire);
+}
diff --git a/libs/hostgraphics/Android.bp b/libs/hostgraphics/Android.bp
index 4407af6..bc2e063 100644
--- a/libs/hostgraphics/Android.bp
+++ b/libs/hostgraphics/Android.bp
@@ -23,6 +23,7 @@
srcs: [
":libui_host_common",
"ADisplay.cpp",
+ "ANativeWindow.cpp",
"Fence.cpp",
"HostBufferQueue.cpp",
"PublicFormat.cpp",
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 4706699..ac38b6d 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -96,6 +96,7 @@
],
cflags: [
"-Wno-unused-variable",
+ "-D__INTRODUCED_IN(n)=",
],
},
},
@@ -539,6 +540,7 @@
"pipeline/skia/ReorderBarrierDrawables.cpp",
"pipeline/skia/TransformCanvas.cpp",
"renderstate/RenderState.cpp",
+ "renderthread/CanvasContext.cpp",
"renderthread/Frame.cpp",
"renderthread/RenderTask.cpp",
"renderthread/TimeLord.cpp",
@@ -589,6 +591,7 @@
"SkiaCanvas.cpp",
"SkiaInterpolator.cpp",
"Tonemapper.cpp",
+ "TreeInfo.cpp",
"VectorDrawable.cpp",
],
@@ -617,7 +620,6 @@
"pipeline/skia/VkFunctorDrawable.cpp",
"pipeline/skia/VkInteropFunctorDrawable.cpp",
"renderthread/CacheManager.cpp",
- "renderthread/CanvasContext.cpp",
"renderthread/DrawFrameTask.cpp",
"renderthread/EglManager.cpp",
"renderthread/ReliableSurface.cpp",
@@ -636,7 +638,6 @@
"Layer.cpp",
"ProfileDataContainer.cpp",
"Readback.cpp",
- "TreeInfo.cpp",
"WebViewFunctorManager.cpp",
"protos/graphicsstats.proto",
],
@@ -654,6 +655,8 @@
srcs: [
"platform/host/renderthread/CacheManager.cpp",
+ "platform/host/renderthread/HintSessionWrapper.cpp",
+ "platform/host/renderthread/ReliableSurface.cpp",
"platform/host/renderthread/RenderThread.cpp",
"platform/host/ProfileDataContainer.cpp",
"platform/host/Readback.cpp",
diff --git a/libs/hwui/apex/LayoutlibLoader.cpp b/libs/hwui/apex/LayoutlibLoader.cpp
index 770822a..fd9915a 100644
--- a/libs/hwui/apex/LayoutlibLoader.cpp
+++ b/libs/hwui/apex/LayoutlibLoader.cpp
@@ -164,8 +164,10 @@
} // namespace android
using namespace android;
+using namespace android::uirenderer;
void init_android_graphics() {
+ Properties::overrideRenderPipelineType(RenderPipelineType::SkiaCpu);
SkGraphics::Init();
}
diff --git a/libs/hwui/platform/host/WebViewFunctorManager.cpp b/libs/hwui/platform/host/WebViewFunctorManager.cpp
index 1d16655..ed50190 100644
--- a/libs/hwui/platform/host/WebViewFunctorManager.cpp
+++ b/libs/hwui/platform/host/WebViewFunctorManager.cpp
@@ -50,6 +50,8 @@
void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {}
+void WebViewFunctor::reportRenderingThreads(const int32_t* thread_ids, size_t size) {}
+
void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {}
WebViewFunctorManager& WebViewFunctorManager::instance() {
@@ -68,6 +70,13 @@
void WebViewFunctorManager::destroyFunctor(int functor) {}
+void WebViewFunctorManager::reportRenderingThreads(int functor, const int32_t* thread_ids,
+ size_t size) {}
+
+std::vector<int32_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() {
+ return std::vector<int32_t>();
+}
+
sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) {
return nullptr;
}
diff --git a/libs/hwui/platform/host/renderthread/HintSessionWrapper.cpp b/libs/hwui/platform/host/renderthread/HintSessionWrapper.cpp
new file mode 100644
index 0000000..b1b1d58
--- /dev/null
+++ b/libs/hwui/platform/host/renderthread/HintSessionWrapper.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 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 "renderthread/HintSessionWrapper.h"
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+void HintSessionWrapper::HintSessionBinding::init() {}
+
+HintSessionWrapper::HintSessionWrapper(pid_t uiThreadId, pid_t renderThreadId)
+ : mUiThreadId(uiThreadId)
+ , mRenderThreadId(renderThreadId)
+ , mBinding(std::make_shared<HintSessionBinding>()) {}
+
+HintSessionWrapper::~HintSessionWrapper() {}
+
+void HintSessionWrapper::destroy() {}
+
+bool HintSessionWrapper::init() {
+ return false;
+}
+
+void HintSessionWrapper::updateTargetWorkDuration(long targetWorkDurationNanos) {}
+
+void HintSessionWrapper::reportActualWorkDuration(long actualDurationNanos) {}
+
+void HintSessionWrapper::sendLoadResetHint() {}
+
+void HintSessionWrapper::sendLoadIncreaseHint() {}
+
+bool HintSessionWrapper::alive() {
+ return false;
+}
+
+nsecs_t HintSessionWrapper::getLastUpdate() {
+ return -1;
+}
+
+void HintSessionWrapper::delayedDestroy(RenderThread& rt, nsecs_t delay,
+ std::shared_ptr<HintSessionWrapper> wrapperPtr) {}
+
+void HintSessionWrapper::setActiveFunctorThreads(std::vector<pid_t> threadIds) {}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/platform/host/renderthread/ReliableSurface.cpp b/libs/hwui/platform/host/renderthread/ReliableSurface.cpp
new file mode 100644
index 0000000..2deaaf3
--- /dev/null
+++ b/libs/hwui/platform/host/renderthread/ReliableSurface.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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 "renderthread/ReliableSurface.h"
+
+#include <log/log_main.h>
+#include <system/window.h>
+
+namespace android::uirenderer::renderthread {
+
+ReliableSurface::ReliableSurface(ANativeWindow* window) : mWindow(window) {
+ LOG_ALWAYS_FATAL_IF(!mWindow, "Error, unable to wrap a nullptr");
+ ANativeWindow_acquire(mWindow);
+}
+
+ReliableSurface::~ReliableSurface() {
+ ANativeWindow_release(mWindow);
+}
+
+void ReliableSurface::init() {}
+
+int ReliableSurface::reserveNext() {
+ return OK;
+}
+
+}; // namespace android::uirenderer::renderthread
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 22de2f2..b06ad6f 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -35,6 +35,7 @@
#include "Properties.h"
#include "RenderThread.h"
#include "hwui/Canvas.h"
+#include "pipeline/skia/SkiaCpuPipeline.h"
#include "pipeline/skia/SkiaGpuPipeline.h"
#include "pipeline/skia/SkiaOpenGLPipeline.h"
#include "pipeline/skia/SkiaVulkanPipeline.h"
@@ -84,6 +85,12 @@
return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
std::make_unique<skiapipeline::SkiaVulkanPipeline>(thread),
uiThreadId, renderThreadId);
+#ifndef __ANDROID__
+ case RenderPipelineType::SkiaCpu:
+ return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
+ std::make_unique<skiapipeline::SkiaCpuPipeline>(thread),
+ uiThreadId, renderThreadId);
+#endif
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
break;
@@ -182,6 +189,7 @@
}
void CanvasContext::setHardwareBuffer(AHardwareBuffer* buffer) {
+#ifdef __ANDROID__
if (mHardwareBuffer) {
AHardwareBuffer_release(mHardwareBuffer);
mHardwareBuffer = nullptr;
@@ -192,6 +200,7 @@
mHardwareBuffer = buffer;
}
mRenderPipeline->setHardwareBuffer(mHardwareBuffer);
+#endif
}
void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
@@ -561,6 +570,7 @@
}
void CanvasContext::draw(bool solelyTextureViewUpdates) {
+#ifdef __ANDROID__
if (auto grContext = getGrContext()) {
if (grContext->abandoned()) {
if (grContext->isDeviceLost()) {
@@ -571,6 +581,7 @@
return;
}
}
+#endif
SkRect dirty;
mDamageAccumulator.finish(&dirty);
@@ -594,11 +605,13 @@
if (skippedFrameReason) {
mCurrentFrameInfo->setSkippedFrameReason(*skippedFrameReason);
+#ifdef __ANDROID__
if (auto grContext = getGrContext()) {
// Submit to ensure that any texture uploads complete and Skia can
// free its staging buffers.
grContext->flushAndSubmit();
}
+#endif
// Notify the callbacks, even if there's nothing to draw so they aren't waiting
// indefinitely
diff --git a/libs/hwui/renderthread/ReliableSurface.h b/libs/hwui/renderthread/ReliableSurface.h
index 5959647..d6a4d50 100644
--- a/libs/hwui/renderthread/ReliableSurface.h
+++ b/libs/hwui/renderthread/ReliableSurface.h
@@ -21,7 +21,9 @@
#include <apex/window.h>
#include <utils/Errors.h>
#include <utils/Macros.h>
+#ifdef __ANDROID__
#include <utils/NdkUtils.h>
+#endif
#include <utils/StrongPointer.h>
#include <memory>
@@ -62,9 +64,11 @@
mutable std::mutex mMutex;
uint64_t mUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
+#ifdef __ANDROID__
AHardwareBuffer_Format mFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
UniqueAHardwareBuffer mScratchBuffer;
ANativeWindowBuffer* mReservedBuffer = nullptr;
+#endif
base::unique_fd mReservedFenceFd;
bool mHasDequeuedBuffer = false;
int mBufferQueueState = OK;