Add a sprinkle of speculative anti-crash dust
Bugs: way too many
Bug: 113367810
Test: well it builds...
Change-Id: If00bcaad1c535c4996b59c1b5a7d3a4bba849191
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index d401b38..6ae5999 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -164,7 +164,11 @@
if (surface) {
mRenderThread.requireGlContext();
- mEglSurface = mEglManager.createSurface(surface, colorMode);
+ auto newSurface = mEglManager.createSurface(surface, colorMode);
+ if (!newSurface) {
+ return false;
+ }
+ mEglSurface = newSurface.unwrap();
}
if (colorMode == ColorMode::SRGB) {
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index d4ffddd..65ced6a 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -261,7 +261,7 @@
}
}
-EGLSurface EglManager::createSurface(EGLNativeWindowType window, ColorMode colorMode) {
+Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window, ColorMode colorMode) {
LOG_ALWAYS_FATAL_IF(!hasEglContext(), "Not initialized");
bool wideColorGamut = colorMode == ColorMode::WideColorGamut && EglExtensions.glColorSpace &&
@@ -311,9 +311,9 @@
EGLSurface surface = eglCreateWindowSurface(
mEglDisplay, wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
- LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE,
- "Failed to create EGLSurface for window %p, eglErr = %s", (void*)window,
- eglErrorString());
+ if (surface == EGL_NO_SURFACE) {
+ return Error<EGLint> { eglGetError() };
+ }
if (mSwapBehavior != SwapBehavior::Preserved) {
LOG_ALWAYS_FATAL_IF(eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR,
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index 55c81d4..2a44f7e 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -25,6 +25,7 @@
#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>
#include "IRenderPipeline.h"
+#include "utils/Result.h"
namespace android {
namespace uirenderer {
@@ -47,7 +48,7 @@
bool hasEglContext();
- EGLSurface createSurface(EGLNativeWindowType window, ColorMode colorMode);
+ Result<EGLSurface, EGLint> createSurface(EGLNativeWindowType window, ColorMode colorMode);
void destroySurface(EGLSurface surface);
void destroy();
diff --git a/libs/hwui/tests/unit/RenderNodeTests.cpp b/libs/hwui/tests/unit/RenderNodeTests.cpp
index 0795208..a6073eb 100644
--- a/libs/hwui/tests/unit/RenderNodeTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeTests.cpp
@@ -321,7 +321,7 @@
// Check that the VD is in the dislay list, and the layer update queue contains the correct
// damage rect.
EXPECT_TRUE(rootNode->getDisplayList()->hasVectorDrawables());
- EXPECT_FALSE(info.layerUpdateQueue->entries().empty());
+ ASSERT_FALSE(info.layerUpdateQueue->entries().empty());
EXPECT_EQ(rootNode.get(), info.layerUpdateQueue->entries().at(0).renderNode.get());
EXPECT_EQ(uirenderer::Rect(0, 0, 200, 400), info.layerUpdateQueue->entries().at(0).damage);
canvasContext->destroy();
diff --git a/libs/hwui/utils/Result.h b/libs/hwui/utils/Result.h
new file mode 100644
index 0000000..7f33f2e
--- /dev/null
+++ b/libs/hwui/utils/Result.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <variant>
+#include <log/log.h>
+
+namespace android::uirenderer {
+
+template <typename E>
+struct Error {
+ E error;
+};
+
+template <typename R, typename E>
+class Result {
+public:
+ Result(const R& r) : result(std::forward<R>(r)) {}
+ Result(R&& r) : result(std::forward<R>(r)) {}
+ Result(Error<E>&& error) : result(std::forward<Error<E>>(error)) {}
+
+ operator bool() const {
+ return result.index() == 0;
+ }
+
+ R unwrap() const {
+ LOG_ALWAYS_FATAL_IF(result.index() == 1, "unwrap called on error value!");
+ return std::get<R>(result);
+ }
+
+ E error() const {
+ LOG_ALWAYS_FATAL_IF(result.index() == 0, "No error to get from Result");
+ return std::get<Error<E>>(result).error;
+ }
+
+private:
+ std::variant<R, Error<E>> result;
+};
+
+}; // namespace android::uirenderer