Merge changes Iea02806d,I45af7b49,Id50e0d23
* changes:
Revert "Bind to FBO when using GPU composition"
Revert "Remove gl surfaces from DisplayDevice."
Revert "Delete renderengine::Surface"
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index beaf9ee..7efc8bd 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -50,6 +50,7 @@
"gl/GLExtensions.cpp",
"gl/GLFramebuffer.cpp",
"gl/GLImage.cpp",
+ "gl/GLSurface.cpp",
"gl/Program.cpp",
"gl/ProgramCache.cpp",
],
diff --git a/libs/renderengine/gl/GLES20RenderEngine.cpp b/libs/renderengine/gl/GLES20RenderEngine.cpp
index d35762d..70a4322 100644
--- a/libs/renderengine/gl/GLES20RenderEngine.cpp
+++ b/libs/renderengine/gl/GLES20RenderEngine.cpp
@@ -41,6 +41,7 @@
#include "GLExtensions.h"
#include "GLFramebuffer.h"
#include "GLImage.h"
+#include "GLSurface.h"
#include "Program.h"
#include "ProgramCache.h"
@@ -274,8 +275,6 @@
// now figure out what version of GL did we actually get
// NOTE: a dummy surface is not needed if KHR_create_context is supported
- // TODO(alecmouri): don't create this surface if EGL_KHR_surfaceless_context
- // is supported.
EGLConfig dummyConfig = config;
if (dummyConfig == EGL_NO_CONFIG) {
@@ -302,10 +301,10 @@
break;
case GLES_VERSION_2_0:
case GLES_VERSION_3_0:
- engine = std::make_unique<GLES20RenderEngine>(featureFlags, display, config, ctxt,
- dummy);
+ engine = std::make_unique<GLES20RenderEngine>(featureFlags);
break;
}
+ engine->setEGLHandles(display, config, ctxt);
ALOGI("OpenGL ES informations:");
ALOGI("vendor : %s", extensions.getVendor());
@@ -315,6 +314,9 @@
ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize());
ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims());
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(display, dummy);
+
return engine;
}
@@ -357,13 +359,11 @@
return config;
}
-GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags, EGLDisplay display, EGLConfig config,
- EGLContext ctxt, EGLSurface dummy)
+GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags)
: renderengine::impl::RenderEngine(featureFlags),
- mEGLDisplay(display),
- mEGLConfig(config),
- mEGLContext(ctxt),
- mDummySurface(dummy),
+ mEGLDisplay(EGL_NO_DISPLAY),
+ mEGLConfig(nullptr),
+ mEGLContext(EGL_NO_CONTEXT),
mVpWidth(0),
mVpHeight(0),
mUseColorManagement(featureFlags & USE_COLOR_MANAGEMENT) {
@@ -422,6 +422,10 @@
return std::make_unique<GLFramebuffer>(*this);
}
+std::unique_ptr<Surface> GLES20RenderEngine::createSurface() {
+ return std::make_unique<GLSurface>(*this);
+}
+
std::unique_ptr<Image> GLES20RenderEngine::createImage() {
return std::make_unique<GLImage>(*this);
}
@@ -434,6 +438,31 @@
return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
}
+bool GLES20RenderEngine::setCurrentSurface(const Surface& surface) {
+ // Surface is an abstract interface. GLES20RenderEngine only ever
+ // creates GLSurface's, so it is safe to just cast to the actual
+ // type.
+ bool success = true;
+ const GLSurface& glSurface = static_cast<const GLSurface&>(surface);
+ EGLSurface eglSurface = glSurface.getEGLSurface();
+ if (eglSurface != eglGetCurrentSurface(EGL_DRAW)) {
+ success = eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext) == EGL_TRUE;
+ if (success && glSurface.getAsync()) {
+ eglSwapInterval(mEGLDisplay, 0);
+ }
+ if (success) {
+ mSurfaceHeight = glSurface.getHeight();
+ }
+ }
+
+ return success;
+}
+
+void GLES20RenderEngine::resetCurrentSurface() {
+ eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ mSurfaceHeight = 0;
+}
+
base::unique_fd GLES20RenderEngine::flush() {
if (!GLExtensions::getInstance().hasNativeFenceSync()) {
return base::unique_fd();
@@ -547,7 +576,7 @@
void GLES20RenderEngine::setScissor(const Rect& region) {
// Invert y-coordinate to map to GL-space.
- int32_t canvasHeight = mFboHeight;
+ int32_t canvasHeight = mRenderToFbo ? mFboHeight : mSurfaceHeight;
int32_t glBottom = canvasHeight - region.bottom;
glScissor(region.left, glBottom, region.getWidth(), region.getHeight());
@@ -590,6 +619,7 @@
glBindFramebuffer(GL_FRAMEBUFFER, framebufferName);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureName, 0);
+ mRenderToFbo = true;
mFboHeight = glFramebuffer->getBufferHeight();
uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -601,10 +631,17 @@
}
void GLES20RenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
+ mRenderToFbo = false;
mFboHeight = 0;
// back to main framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Workaround for b/77935566 to force the EGL driver to release the
+ // screenshot buffer
+ setScissor(Rect::EMPTY_RECT);
+ clearWithColor(0.0, 0.0, 0.0, 0.0);
+ disableScissor();
}
void GLES20RenderEngine::checkErrors() const {
@@ -629,7 +666,9 @@
int32_t r = sourceCrop.right;
int32_t b = sourceCrop.bottom;
int32_t t = sourceCrop.top;
- std::swap(t, b);
+ if (mRenderToFbo) {
+ std::swap(t, b);
+ }
mat4 m = mat4::ortho(l, r, b, t, 0, 1);
// Apply custom rotation to the projection.
@@ -935,6 +974,12 @@
return (isInputHdrDataSpace || isOutputHdrDataSpace) && inputTransfer != outputTransfer;
}
+void GLES20RenderEngine::setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt) {
+ mEGLDisplay = display;
+ mEGLConfig = config;
+ mEGLContext = ctxt;
+}
+
} // namespace gl
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/gl/GLES20RenderEngine.h b/libs/renderengine/gl/GLES20RenderEngine.h
index 6c50938..148df2f 100644
--- a/libs/renderengine/gl/GLES20RenderEngine.h
+++ b/libs/renderengine/gl/GLES20RenderEngine.h
@@ -40,21 +40,24 @@
namespace gl {
class GLImage;
+class GLSurface;
class GLES20RenderEngine : public impl::RenderEngine {
public:
static std::unique_ptr<GLES20RenderEngine> create(int hwcFormat, uint32_t featureFlags);
static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
- GLES20RenderEngine(uint32_t featureFlags, // See RenderEngine::FeatureFlag
- EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy);
+ GLES20RenderEngine(uint32_t featureFlags); // See RenderEngine::FeatureFlag
~GLES20RenderEngine() override;
std::unique_ptr<Framebuffer> createFramebuffer() override;
+ std::unique_ptr<Surface> createSurface() override;
std::unique_ptr<Image> createImage() override;
void primeCache() const override;
bool isCurrent() const override;
+ bool setCurrentSurface(const Surface& surface) override;
+ void resetCurrentSurface() override;
base::unique_fd flush() override;
bool finish() override;
bool waitFence(base::unique_fd fenceFd) override;
@@ -117,12 +120,11 @@
// with PQ or HLG transfer function.
bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
bool needsXYZTransformMatrix() const;
- void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy);
+ void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt);
EGLDisplay mEGLDisplay;
EGLConfig mEGLConfig;
EGLContext mEGLContext;
- EGLSurface mDummySurface;
GLuint mProtectedTexName;
GLint mMaxViewportDims[2];
GLint mMaxTextureSize;
@@ -143,6 +145,8 @@
mat4 mBt2020ToSrgb;
mat4 mBt2020ToDisplayP3;
+ bool mRenderToFbo = false;
+ int32_t mSurfaceHeight = 0;
int32_t mFboHeight = 0;
// Current dataspace of layer being rendered
diff --git a/libs/renderengine/gl/GLSurface.cpp b/libs/renderengine/gl/GLSurface.cpp
new file mode 100644
index 0000000..2d694e9
--- /dev/null
+++ b/libs/renderengine/gl/GLSurface.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright 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 "GLSurface.h"
+
+#include <android/native_window.h>
+#include <log/log.h>
+#include <ui/PixelFormat.h>
+#include "GLES20RenderEngine.h"
+
+namespace android {
+namespace renderengine {
+namespace gl {
+
+GLSurface::GLSurface(const GLES20RenderEngine& engine)
+ : mEGLDisplay(engine.getEGLDisplay()), mEGLConfig(engine.getEGLConfig()) {
+ // RE does not assume any config when EGL_KHR_no_config_context is supported
+ if (mEGLConfig == EGL_NO_CONFIG_KHR) {
+ mEGLConfig =
+ GLES20RenderEngine::chooseEglConfig(mEGLDisplay, PIXEL_FORMAT_RGBA_8888, false);
+ }
+}
+
+GLSurface::~GLSurface() {
+ setNativeWindow(nullptr);
+}
+
+void GLSurface::setNativeWindow(ANativeWindow* window) {
+ if (mEGLSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(mEGLDisplay, mEGLSurface);
+ mEGLSurface = EGL_NO_SURFACE;
+ mSurfaceWidth = 0;
+ mSurfaceHeight = 0;
+ }
+
+ mWindow = window;
+ if (mWindow) {
+ mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mWindow, nullptr);
+ mSurfaceWidth = ANativeWindow_getWidth(window);
+ mSurfaceHeight = ANativeWindow_getHeight(window);
+ }
+}
+
+void GLSurface::swapBuffers() const {
+ if (!eglSwapBuffers(mEGLDisplay, mEGLSurface)) {
+ EGLint error = eglGetError();
+
+ const char format[] = "eglSwapBuffers(%p, %p) failed with 0x%08x";
+ if (mCritical || error == EGL_CONTEXT_LOST) {
+ LOG_ALWAYS_FATAL(format, mEGLDisplay, mEGLSurface, error);
+ } else {
+ ALOGE(format, mEGLDisplay, mEGLSurface, error);
+ }
+ }
+}
+
+EGLint GLSurface::queryConfig(EGLint attrib) const {
+ EGLint value;
+ if (!eglGetConfigAttrib(mEGLDisplay, mEGLConfig, attrib, &value)) {
+ value = 0;
+ }
+
+ return value;
+}
+
+int32_t GLSurface::queryRedSize() const {
+ return queryConfig(EGL_RED_SIZE);
+}
+
+int32_t GLSurface::queryGreenSize() const {
+ return queryConfig(EGL_GREEN_SIZE);
+}
+
+int32_t GLSurface::queryBlueSize() const {
+ return queryConfig(EGL_BLUE_SIZE);
+}
+
+int32_t GLSurface::queryAlphaSize() const {
+ return queryConfig(EGL_ALPHA_SIZE);
+}
+
+int32_t GLSurface::getWidth() const {
+ return mSurfaceWidth;
+}
+
+int32_t GLSurface::getHeight() const {
+ return mSurfaceHeight;
+}
+
+} // namespace gl
+} // namespace renderengine
+} // namespace android
diff --git a/libs/renderengine/gl/GLSurface.h b/libs/renderengine/gl/GLSurface.h
new file mode 100644
index 0000000..092d371
--- /dev/null
+++ b/libs/renderengine/gl/GLSurface.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 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 <cstdint>
+
+#include <EGL/egl.h>
+#include <android-base/macros.h>
+#include <renderengine/Surface.h>
+
+struct ANativeWindow;
+
+namespace android {
+namespace renderengine {
+namespace gl {
+
+class GLES20RenderEngine;
+
+class GLSurface final : public renderengine::Surface {
+public:
+ GLSurface(const GLES20RenderEngine& engine);
+ ~GLSurface() override;
+
+ // renderengine::Surface implementation
+ void setCritical(bool enable) override { mCritical = enable; }
+ void setAsync(bool enable) override { mAsync = enable; }
+
+ void setNativeWindow(ANativeWindow* window) override;
+ void swapBuffers() const override;
+
+ int32_t queryRedSize() const override;
+ int32_t queryGreenSize() const override;
+ int32_t queryBlueSize() const override;
+ int32_t queryAlphaSize() const override;
+
+ bool getAsync() const { return mAsync; }
+ EGLSurface getEGLSurface() const { return mEGLSurface; }
+
+ int32_t getWidth() const override;
+ int32_t getHeight() const override;
+
+private:
+ EGLint queryConfig(EGLint attrib) const;
+
+ EGLDisplay mEGLDisplay;
+ EGLConfig mEGLConfig;
+
+ bool mCritical = false;
+ bool mAsync = false;
+
+ int32_t mSurfaceWidth = 0;
+ int32_t mSurfaceHeight = 0;
+
+ ANativeWindow* mWindow = nullptr;
+ EGLSurface mEGLSurface = EGL_NO_SURFACE;
+
+ DISALLOW_COPY_AND_ASSIGN(GLSurface);
+};
+
+} // namespace gl
+} // namespace renderengine
+} // namespace android
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 22891c4..becb3c3 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -48,6 +48,7 @@
class BindNativeBufferAsFramebuffer;
class Image;
class Mesh;
+class Surface;
class Texture;
namespace impl {
@@ -71,6 +72,7 @@
// used to support legacy behavior.
virtual std::unique_ptr<Framebuffer> createFramebuffer() = 0;
+ virtual std::unique_ptr<Surface> createSurface() = 0;
virtual std::unique_ptr<Image> createImage() = 0;
virtual void primeCache() const = 0;
@@ -82,6 +84,8 @@
virtual bool useWaitSync() const = 0;
virtual bool isCurrent() const = 0;
+ virtual bool setCurrentSurface(const Surface& surface) = 0;
+ virtual void resetCurrentSurface() = 0;
// helpers
// flush submits RenderEngine command stream for execution and returns a
diff --git a/libs/renderengine/include/renderengine/Surface.h b/libs/renderengine/include/renderengine/Surface.h
new file mode 100644
index 0000000..ba7331d
--- /dev/null
+++ b/libs/renderengine/include/renderengine/Surface.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+struct ANativeWindow;
+
+namespace android {
+namespace renderengine {
+
+class Surface {
+public:
+ virtual ~Surface() = default;
+
+ virtual void setCritical(bool enable) = 0;
+ virtual void setAsync(bool enable) = 0;
+
+ virtual void setNativeWindow(ANativeWindow* window) = 0;
+ virtual void swapBuffers() const = 0;
+
+ virtual int32_t queryRedSize() const = 0;
+ virtual int32_t queryGreenSize() const = 0;
+ virtual int32_t queryBlueSize() const = 0;
+ virtual int32_t queryAlphaSize() const = 0;
+
+ virtual int32_t getWidth() const = 0;
+ virtual int32_t getHeight() const = 0;
+};
+
+} // namespace renderengine
+} // namespace android
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 9abb040..f168db9 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -184,7 +184,6 @@
"libhidltransport",
"liblayers_proto",
"liblog",
- "libsync",
"libtimestats_proto",
"libutils",
],
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index d16febf..5342bcf 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -35,8 +35,6 @@
#include <gui/Surface.h>
#include <hardware/gralloc.h>
#include <renderengine/RenderEngine.h>
-#include <sync/sync.h>
-#include <system/window.h>
#include <ui/DebugUtils.h>
#include <ui/DisplayInfo.h>
#include <ui/PixelFormat.h>
@@ -223,8 +221,8 @@
mDisplayToken(args.displayToken),
mId(args.displayId),
mNativeWindow(args.nativeWindow),
- mGraphicBuffer(nullptr),
mDisplaySurface(args.displaySurface),
+ mSurface{std::move(args.renderSurface)},
mDisplayInstallOrientation(args.displayInstallOrientation),
mPageFlipCount(0),
mIsVirtual(args.isVirtual),
@@ -246,6 +244,7 @@
ALOGE_IF(!mNativeWindow, "No native window was set for display");
ALOGE_IF(!mDisplaySurface, "No display surface was set for display");
+ ALOGE_IF(!mSurface, "No render surface was set for display");
std::vector<Hdr> types = args.hdrCapabilities.getSupportedHdrTypes();
for (Hdr hdrType : types) {
@@ -285,10 +284,6 @@
mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);
ANativeWindow* const window = mNativeWindow.get();
-
- int status = native_window_api_connect(mNativeWindow.get(), NATIVE_WINDOW_API_EGL);
- ALOGE_IF(status != NO_ERROR, "Unable to connect BQ producer: %d", status);
-
mDisplayWidth = ANativeWindow_getWidth(window);
mDisplayHeight = ANativeWindow_getHeight(window);
@@ -326,6 +321,7 @@
void DisplayDevice::flip() const
{
+ mFlinger->getRenderEngine().checkErrors();
mPageFlipCount++;
}
@@ -360,71 +356,9 @@
return mDisplaySurface->prepareFrame(compositionType);
}
-sp<GraphicBuffer> DisplayDevice::dequeueBuffer() {
- int fd;
- ANativeWindowBuffer* buffer;
-
- status_t res = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fd);
-
- if (res != NO_ERROR) {
- ALOGE("ANativeWindow::dequeueBuffer failed for display [%s] with error: %d",
- getDisplayName().c_str(), res);
- // Return fast here as we can't do much more - any rendering we do
- // now will just be wrong.
- return mGraphicBuffer;
- }
-
- ALOGW_IF(mGraphicBuffer != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
- mGraphicBuffer->getNativeBuffer()->handle);
- mGraphicBuffer = GraphicBuffer::from(buffer);
-
- // Block until the buffer is ready
- // TODO(alecmouri): it's perhaps more appropriate to block renderengine so
- // that the gl driver can block instead.
- if (fd >= 0) {
- sync_wait(fd, -1);
- close(fd);
- }
-
- return mGraphicBuffer;
-}
-
-void DisplayDevice::queueBuffer(HWComposer& hwc) {
+void DisplayDevice::swapBuffers(HWComposer& hwc) const {
if (hwc.hasClientComposition(mId) || hwc.hasFlipClientTargetRequest(mId)) {
- // hasFlipClientTargetRequest could return true even if we haven't
- // dequeued a buffer before. Try dequeueing one if we don't have a
- // buffer ready.
- if (mGraphicBuffer == nullptr) {
- ALOGI("Attempting to queue a client composited buffer without one "
- "previously dequeued for display [%s]. Attempting to dequeue "
- "a scratch buffer now",
- mDisplayName.c_str());
- // We shouldn't deadlock here, since mGraphicBuffer == nullptr only
- // after a successful call to queueBuffer, or if dequeueBuffer has
- // never been called.
- dequeueBuffer();
- }
-
- if (mGraphicBuffer == nullptr) {
- ALOGE("No buffer is ready for display [%s]", mDisplayName.c_str());
- } else {
- int fd = mBufferReady.release();
-
- status_t res = mNativeWindow->queueBuffer(mNativeWindow.get(),
- mGraphicBuffer->getNativeBuffer(), fd);
- if (res != NO_ERROR) {
- ALOGE("Error when queueing buffer for display [%s]: %d", mDisplayName.c_str(), res);
- // We risk blocking on dequeueBuffer if the primary display failed
- // to queue up its buffer, so crash here.
- if (isPrimary()) {
- LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", res);
- } else {
- mNativeWindow->cancelBuffer(mNativeWindow.get(),
- mGraphicBuffer->getNativeBuffer(), fd);
- }
- }
- mGraphicBuffer = nullptr;
- }
+ mSurface->swapBuffers();
}
status_t result = mDisplaySurface->advanceFrame();
@@ -433,10 +367,16 @@
}
}
-void DisplayDevice::onPresentDisplayCompleted() {
+void DisplayDevice::onSwapBuffersCompleted() const {
mDisplaySurface->onFrameCommitted();
}
+bool DisplayDevice::makeCurrent() const {
+ bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface);
+ setViewportAndProjection();
+ return success;
+}
+
void DisplayDevice::setViewportAndProjection() const {
size_t w = mDisplayWidth;
size_t h = mDisplayHeight;
@@ -444,13 +384,6 @@
mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, ui::Transform::ROT_0);
}
-void DisplayDevice::finishBuffer() {
- mBufferReady = mFlinger->getRenderEngine().flush();
- if (mBufferReady.get() < 0) {
- mFlinger->getRenderEngine().finish();
- }
-}
-
const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
return mDisplaySurface->getClientTargetAcquireFence();
}
@@ -599,8 +532,12 @@
void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
dirtyRegion.set(getBounds());
+ mSurface->setNativeWindow(nullptr);
+
mDisplaySurface->resizeBuffers(newWidth, newHeight);
+ ANativeWindow* const window = mNativeWindow.get();
+ mSurface->setNativeWindow(window);
mDisplayWidth = newWidth;
mDisplayHeight = newHeight;
}
@@ -716,11 +653,12 @@
ANativeWindow* const window = mNativeWindow.get();
result.appendFormat("+ %s\n", getDebugName().c_str());
result.appendFormat(" layerStack=%u, (%4dx%4d), ANativeWindow=%p "
- "format=%d, orient=%2d (type=%08x), flips=%u, isSecure=%d, "
- "powerMode=%d, activeConfig=%d, numLayers=%zu\n",
+ "(%d:%d:%d:%d), orient=%2d (type=%08x), "
+ "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
mLayerStack, mDisplayWidth, mDisplayHeight, window,
- ANativeWindow_getFormat(window), mOrientation, tr.getType(),
- getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
+ mSurface->queryRedSize(), mSurface->queryGreenSize(),
+ mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation,
+ tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
mVisibleLayersSortedByZ.size());
result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
@@ -731,9 +669,9 @@
auto const surface = static_cast<Surface*>(window);
ui::Dataspace dataspace = surface->getBuffersDataSpace();
result.appendFormat(" wideColorGamut=%d, hdr10=%d, colorMode=%s, dataspace: %s (%d)\n",
- mHasWideColorGamut, mHasHdr10, decodeColorMode(mActiveColorMode).c_str(),
- dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(),
- dataspace);
+ mHasWideColorGamut, mHasHdr10,
+ decodeColorMode(mActiveColorMode).c_str(),
+ dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(), dataspace);
String8 surfaceDump;
mDisplaySurface->dumpAsString(surfaceDump);
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index eb2c5c3..bcd3330 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -24,25 +24,25 @@
#include <string>
#include <unordered_map>
-#include <android/native_window.h>
#include <binder/IBinder.h>
#include <gui/LayerState.h>
#include <hardware/hwcomposer_defs.h>
#include <math/mat4.h>
-#include <renderengine/RenderEngine.h>
-#include <system/window.h>
+#include <renderengine/Surface.h>
#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
#include <ui/Region.h>
#include <ui/Transform.h>
-#include <utils/Mutex.h>
#include <utils/RefBase.h>
+#include <utils/Mutex.h>
#include <utils/String8.h>
#include <utils/Timers.h>
#include "DisplayHardware/DisplayIdentification.h"
#include "RenderArea.h"
+struct ANativeWindow;
+
namespace android {
class DisplaySurface;
@@ -146,13 +146,10 @@
ui::Dataspace* outDataspace, ui::ColorMode* outMode,
ui::RenderIntent* outIntent) const;
- // Queues the drawn buffer for consumption by HWC.
- void queueBuffer(HWComposer& hwc);
- // Allocates a buffer as scratch space for GPU composition
- sp<GraphicBuffer> dequeueBuffer();
+ void swapBuffers(HWComposer& hwc) const;
// called after h/w composer has completed its set() call
- void onPresentDisplayCompleted();
+ void onSwapBuffersCompleted() const;
Rect getBounds() const {
return Rect(mDisplayWidth, mDisplayHeight);
@@ -162,11 +159,7 @@
void setDisplayName(const std::string& displayName);
const std::string& getDisplayName() const { return mDisplayName; }
- // Acquires a new buffer for GPU composition.
- void readyNewBuffer();
- // Marks the current buffer has finished, so that it can be presented and
- // swapped out.
- void finishBuffer();
+ bool makeCurrent() const;
void setViewportAndProjection() const;
const sp<Fence>& getClientTargetAcquireFence() const;
@@ -211,13 +204,9 @@
// ANativeWindow this display is rendering into
sp<ANativeWindow> mNativeWindow;
- // Current buffer that this display can render to.
- sp<GraphicBuffer> mGraphicBuffer;
sp<DisplaySurface> mDisplaySurface;
- // File descriptor indicating that mGraphicBuffer is ready for display, i.e.
- // that drawing to the buffer is now complete.
- base::unique_fd mBufferReady;
+ std::unique_ptr<renderengine::Surface> mSurface;
int mDisplayWidth;
int mDisplayHeight;
const int mDisplayInstallOrientation;
@@ -337,6 +326,7 @@
bool isSecure{false};
sp<ANativeWindow> nativeWindow;
sp<DisplaySurface> displaySurface;
+ std::unique_ptr<renderengine::Surface> renderSurface;
int displayInstallOrientation{DisplayState::eOrientationDefault};
bool hasWideColorGamut{false};
HdrCapabilities hdrCapabilities;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 5f3fcd6..27d3dc5 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -107,6 +107,8 @@
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight);
sink->setAsyncMode(true);
+ IGraphicBufferProducer::QueueBufferOutput output;
+ mSource[SOURCE_SCRATCH]->connect(nullptr, NATIVE_WINDOW_API_EGL, false, &output);
}
VirtualDisplaySurface::~VirtualDisplaySurface() {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e84e21a..25c60fe 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -45,7 +45,6 @@
#include <gui/BufferQueue.h>
#include <gui/GuiConfig.h>
#include <gui/IDisplayEventConnection.h>
-#include <gui/IProducerListener.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
#include <renderengine/RenderEngine.h>
@@ -677,6 +676,10 @@
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
"Internal display is disconnected.");
+ // make the default display GLContext current so that we can create textures
+ // when creating Layers (which may happens before we render something)
+ display->makeCurrent();
+
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
// This callback is called from the vr flinger dispatch thread. We
@@ -1406,6 +1409,7 @@
// mCurrentState and mDrawingState and re-apply all changes when we make the
// transition.
mDrawingState.displays.clear();
+ getRenderEngine().resetCurrentSurface();
mDisplays.clear();
}
@@ -1715,7 +1719,7 @@
auto& engine(getRenderEngine());
engine.fillRegionWithColor(dirtyRegion, 1, 0, 1, 1);
- display->queueBuffer(getHwComposer());
+ display->swapBuffers(getHwComposer());
}
}
@@ -2190,7 +2194,8 @@
if (displayId) {
getHwComposer().presentAndGetReleaseFences(*displayId);
}
- display->onPresentDisplayCompleted();
+ display->onSwapBuffersCompleted();
+ display->makeCurrent();
for (auto& layer : display->getVisibleLayersSortedByZ()) {
sp<Fence> releaseFence = Fence::NO_FENCE;
@@ -2337,9 +2342,22 @@
auto nativeWindow = nativeWindowSurface->getNativeWindow();
creationArgs.nativeWindow = nativeWindow;
+ /*
+ * Create our display's surface
+ */
+ std::unique_ptr<renderengine::Surface> renderSurface = getRenderEngine().createSurface();
+ renderSurface->setCritical(isInternalDisplay);
+ renderSurface->setAsync(state.isVirtual());
+ renderSurface->setNativeWindow(nativeWindow.get());
+ creationArgs.renderSurface = std::move(renderSurface);
+
// Make sure that composition can never be stalled by a virtual display
// consumer that isn't processing buffers fast enough. We have to do this
- // here, in case the display is composed entirely by HWC.
+ // in two places:
+ // * Here, in case the display is composed entirely by HWC.
+ // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
+ // window's swap interval in eglMakeCurrent, so they'll override the
+ // interval we set here.
if (state.isVirtual()) {
nativeWindow->setSwapInterval(nativeWindow.get(), 0);
}
@@ -2399,6 +2417,12 @@
const auto externalDisplayId = getExternalDisplayId();
// in drawing state but not in current state
+ // Call makeCurrent() on the primary display so we can
+ // be sure that nothing associated with this display
+ // is current.
+ if (const auto defaultDisplay = getDefaultDisplayDeviceLocked()) {
+ defaultDisplay->makeCurrent();
+ }
if (const auto display = getDisplayDeviceLocked(draw.keyAt(i))) {
display->disconnect(getHwComposer());
}
@@ -2949,7 +2973,7 @@
mGeometryInvalid = true;
}
-void SurfaceFlinger::doDisplayComposition(const sp<DisplayDevice>& display,
+void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& display,
const Region& inDirtyRegion) {
// We only need to actually compose the display if:
// 1) It is being handled by hardware composer, which may need this to
@@ -2964,10 +2988,10 @@
if (!doComposeSurfaces(display)) return;
// swap buffers (presentation)
- display->queueBuffer(getHwComposer());
+ display->swapBuffers(getHwComposer());
}
-bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& display) {
+bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& display) {
ALOGV("doComposeSurfaces");
const Region bounds(display->bounds());
@@ -2980,31 +3004,9 @@
bool applyColorMatrix = false;
bool needsEnhancedColorMatrix = false;
- // Framebuffer will live in this scope for GPU composition.
- std::unique_ptr<renderengine::BindNativeBufferAsFramebuffer> fbo;
-
if (hasClientComposition) {
ALOGV("hasClientComposition");
- sp<GraphicBuffer> buf = display->dequeueBuffer();
-
- if (buf == nullptr) {
- ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
- "client composition for this frame",
- display->getDisplayName().c_str());
- return false;
- }
-
- // Bind the framebuffer in this scope.
- fbo = std::make_unique<renderengine::BindNativeBufferAsFramebuffer>(getRenderEngine(),
- buf->getNativeBuffer());
-
- if (fbo->getStatus() != NO_ERROR) {
- ALOGW("Binding buffer for display [%s] failed with status: %d",
- display->getDisplayName().c_str(), fbo->getStatus());
- return false;
- }
-
Dataspace outputDataspace = Dataspace::UNKNOWN;
if (display->hasWideColorGamut()) {
outputDataspace = display->getCompositionDataSpace();
@@ -3033,7 +3035,18 @@
colorMatrix *= mEnhancedSaturationMatrix;
}
- display->setViewportAndProjection();
+ if (!display->makeCurrent()) {
+ ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
+ display->getDisplayName().c_str());
+ getRenderEngine().resetCurrentSurface();
+
+ // |mStateLock| not needed as we are on the main thread
+ const auto defaultDisplay = getDefaultDisplayDeviceLocked();
+ if (!defaultDisplay || !defaultDisplay->makeCurrent()) {
+ ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
+ }
+ return false;
+ }
// Never touch the framebuffer if we don't have any framebuffer layers
if (hasDeviceComposition) {
@@ -3126,15 +3139,11 @@
firstLayer = false;
}
- // Perform some cleanup steps if we used client composition.
- if (hasClientComposition) {
- getRenderEngine().setColorTransform(mat4());
- getBE().mRenderEngine->disableScissor();
- display->finishBuffer();
- // Clear out error flags here so that we don't wait until next
- // composition to log.
- getRenderEngine().checkErrors();
- }
+ // Clear color transform matrix at the end of the frame.
+ getRenderEngine().setColorTransform(mat4());
+
+ // disable scissor at the end of the frame
+ getBE().mRenderEngine->disableScissor();
return true;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f5218b1..6ffe025 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -721,10 +721,10 @@
void doDebugFlashRegions(const sp<DisplayDevice>& display, bool repaintEverything);
void doTracing(const char* where);
void logLayerStats();
- void doDisplayComposition(const sp<DisplayDevice>& display, const Region& dirtyRegion);
+ void doDisplayComposition(const sp<const DisplayDevice>& display, const Region& dirtyRegion);
// This fails if using GL and the surface has been destroyed.
- bool doComposeSurfaces(const sp<DisplayDevice>& display);
+ bool doComposeSurfaces(const sp<const DisplayDevice>& display);
void postFramebuffer(const sp<DisplayDevice>& display);
void postFrame();
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index cfaf495..ab1b252 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -46,7 +46,6 @@
using testing::AtLeast;
using testing::ByMove;
using testing::DoAll;
-using testing::Invoke;
using testing::IsNull;
using testing::Mock;
using testing::NotNull;
@@ -94,10 +93,6 @@
EXPECT_CALL(*mPrimaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
EXPECT_CALL(*mPrimaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
- EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
- .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0)));
- EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
- .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0)));
mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
setupComposer(0);
@@ -144,11 +139,9 @@
sp<DisplayDevice> mDisplay;
sp<DisplayDevice> mExternalDisplay;
sp<mock::DisplaySurface> mDisplaySurface = new mock::DisplaySurface();
+ renderengine::mock::Surface* mRenderSurface = new renderengine::mock::Surface();
mock::NativeWindow* mNativeWindow = new mock::NativeWindow();
- sp<GraphicBuffer> mBuffer = new GraphicBuffer();
- ANativeWindowBuffer* mNativeWindowBuffer = mBuffer->getNativeBuffer();
-
mock::EventThread* mEventThread = new mock::EventThread();
mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
@@ -249,6 +242,8 @@
test->mDisplay = FakeDisplayDeviceInjector(test->mFlinger, DEFAULT_DISPLAY_ID,
false /* isVirtual */, true /* isPrimary */)
.setDisplaySurface(test->mDisplaySurface)
+ .setRenderSurface(std::unique_ptr<renderengine::Surface>(
+ test->mRenderSurface))
.setNativeWindow(test->mNativeWindow)
.setSecure(Derived::IS_SECURE)
.setPowerMode(Derived::INIT_POWER_MODE)
@@ -271,9 +266,13 @@
EXPECT_CALL(*test->mRenderEngine, checkErrors()).WillRepeatedly(Return());
EXPECT_CALL(*test->mRenderEngine, isCurrent()).WillRepeatedly(Return(true));
- EXPECT_CALL(*test->mRenderEngine, flush()).WillRepeatedly(Invoke([]() {
- return base::unique_fd(0);
- }));
+ EXPECT_CALL(*test->mRenderEngine, setCurrentSurface(Ref(*test->mRenderSurface)))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*test->mRenderEngine,
+ setViewportAndProjection(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
+ Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+ ui::Transform::ROT_0))
+ .Times(1);
EXPECT_CALL(*test->mDisplaySurface, onFrameCommitted()).Times(1);
EXPECT_CALL(*test->mDisplaySurface, advanceFrame()).Times(1);
@@ -324,6 +323,8 @@
static void setupHwcCompositionCallExpectations(CompositionTest* test) {
EXPECT_CALL(*test->mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC)).Times(1);
+
+ EXPECT_CALL(*test->mRenderEngine, disableScissor()).Times(1);
}
static void setupRECompositionCallExpectations(CompositionTest* test) {
@@ -343,18 +344,12 @@
setViewportAndProjection(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
ui::Transform::ROT_0))
- .Times(1);
- EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull())).WillOnce(Return(true));
- EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull())).WillOnce(Return(true));
- EXPECT_CALL(*test->mRenderEngine, createFramebuffer())
- .WillOnce(Return(
- ByMove(std::unique_ptr<renderengine::Framebuffer>(test->mReFrameBuffer))));
- EXPECT_CALL(*test->mRenderEngine, bindFrameBuffer(test->mReFrameBuffer)).Times(1);
- EXPECT_CALL(*test->mRenderEngine, unbindFrameBuffer(test->mReFrameBuffer)).Times(1);
- EXPECT_CALL(*test->mNativeWindow, queueBuffer(_, _)).WillOnce(Return(0));
- EXPECT_CALL(*test->mNativeWindow, dequeueBuffer(_, _))
- .WillOnce(DoAll(SetArgPointee<0>(test->mNativeWindowBuffer), SetArgPointee<1>(-1),
- Return(0)));
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*test->mRenderEngine, setCurrentSurface(Ref(*test->mRenderSurface)))
+ .WillOnce(Return(true))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*test->mRenderSurface, swapBuffers()).Times(1);
}
template <typename Case>
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index ac6a78b..32fce67 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -120,7 +120,6 @@
mock::EventThread* mEventThread = new mock::EventThread();
mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
- sp<GraphicBuffer> mBuffer = new GraphicBuffer();
// These mocks are created by the test, but are destroyed by SurfaceFlinger
// by virtue of being stored into a std::unique_ptr. However we still need
@@ -135,6 +134,7 @@
sp<mock::GraphicBufferConsumer> mConsumer;
sp<mock::GraphicBufferProducer> mProducer;
surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
+ renderengine::mock::Surface* mRenderSurface = nullptr;
};
DisplayTransactionTest::DisplayTransactionTest() {
@@ -340,11 +340,26 @@
static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
.WillOnce(Return(test->mNativeWindow));
+ EXPECT_CALL(*test->mNativeWindow, perform(19)).WillRepeatedly(Return(NO_ERROR));
+ // For simplicity, we only expect to create a single render surface for
+ // each test.
+ ASSERT_TRUE(test->mRenderSurface == nullptr);
+ test->mRenderSurface = new renderengine::mock::Surface();
+ EXPECT_CALL(*test->mRenderEngine, createSurface())
+ .WillOnce(Return(ByMove(
+ std::unique_ptr<renderengine::Surface>(test->mRenderSurface))));
+
+ // Creating a DisplayDevice requires getting default dimensions from the
+ // native window.
EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
+
+ EXPECT_CALL(*test->mRenderSurface, setAsync(static_cast<bool>(ASYNC))).Times(1);
+ EXPECT_CALL(*test->mRenderSurface, setCritical(static_cast<bool>(CRITICAL))).Times(1);
+ EXPECT_CALL(*test->mRenderSurface, setNativeWindow(test->mNativeWindow.get())).Times(1);
}
static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
@@ -1055,6 +1070,9 @@
// The call disable vsyncs
EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
+ // The call clears the current render engine surface
+ EXPECT_CALL(*mRenderEngine, resetCurrentSurface());
+
// The call ends any display resyncs
EXPECT_CALL(*mPrimaryDispSync, endResync()).Times(1);
@@ -1114,7 +1132,6 @@
.WillRepeatedly(DoAll(SetArgPointee<1>(1080 /* arbitrary */), Return(0)));
EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(1920 /* arbitrary */), Return(0)));
- EXPECT_CALL(*mNativeWindow, perform(13)).Times(1);
auto displayDevice = mInjector.inject();
displayDevice->getBestColorMode(mInputDataspace, mInputRenderIntent, &mOutDataspace,
@@ -1708,6 +1725,7 @@
EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
+ EXPECT_CALL(*mProducer, connect(_, _, _, _)).Times(1);
EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
@@ -1931,16 +1949,11 @@
// A display is set up
auto nativeWindow = new mock::NativeWindow();
auto displaySurface = new mock::DisplaySurface();
- sp<GraphicBuffer> buf = new GraphicBuffer();
+ auto renderSurface = new renderengine::mock::Surface();
auto display = Case::Display::makeFakeExistingDisplayInjector(this);
display.setNativeWindow(nativeWindow);
display.setDisplaySurface(displaySurface);
- // Setup injection expections
- EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
- .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
- EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
- .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
- EXPECT_CALL(*nativeWindow, perform(13)).Times(1);
+ display.setRenderSurface(std::unique_ptr<renderengine::Surface>(renderSurface));
display.inject();
// There is a change to the viewport state
@@ -1952,7 +1965,9 @@
// --------------------------------------------------------------------
// Call Expectations
+ EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
+ EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
// --------------------------------------------------------------------
// Invocation
@@ -1973,16 +1988,11 @@
// A display is set up
auto nativeWindow = new mock::NativeWindow();
auto displaySurface = new mock::DisplaySurface();
- sp<GraphicBuffer> buf = new GraphicBuffer();
+ auto renderSurface = new renderengine::mock::Surface();
auto display = Case::Display::makeFakeExistingDisplayInjector(this);
display.setNativeWindow(nativeWindow);
display.setDisplaySurface(displaySurface);
- // Setup injection expections
- EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
- .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
- EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
- .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
- EXPECT_CALL(*nativeWindow, perform(13)).Times(1);
+ display.setRenderSurface(std::unique_ptr<renderengine::Surface>(renderSurface));
display.inject();
// There is a change to the viewport state
@@ -1994,7 +2004,9 @@
// --------------------------------------------------------------------
// Call Expectations
+ EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
+ EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
// --------------------------------------------------------------------
// Invocation
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 85c835e..a519f1f 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -474,6 +474,11 @@
return *this;
}
+ auto& setRenderSurface(std::unique_ptr<renderengine::Surface> renderSurface) {
+ mCreationArgs.renderSurface = std::move(renderSurface);
+ return *this;
+ }
+
auto& setSecure(bool secure) {
mCreationArgs.isSecure = secure;
return *this;
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
index fbfbc3f..af54df6 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
@@ -26,6 +26,9 @@
RenderEngine::RenderEngine() = default;
RenderEngine::~RenderEngine() = default;
+Surface::Surface() = default;
+Surface::~Surface() = default;
+
Image::Image() = default;
Image::~Image() = default;
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 90c3c20..afca63a 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -23,6 +23,7 @@
#include <renderengine/LayerSettings.h>
#include <renderengine/Mesh.h>
#include <renderengine/RenderEngine.h>
+#include <renderengine/Surface.h>
#include <renderengine/Texture.h>
#include <ui/GraphicBuffer.h>
@@ -36,12 +37,15 @@
~RenderEngine() override;
MOCK_METHOD0(createFramebuffer, std::unique_ptr<Framebuffer>());
+ MOCK_METHOD0(createSurface, std::unique_ptr<renderengine::Surface>());
MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
MOCK_CONST_METHOD0(primeCache, void());
MOCK_METHOD1(dump, void(String8&));
MOCK_CONST_METHOD0(useNativeFenceSync, bool());
MOCK_CONST_METHOD0(useWaitSync, bool());
MOCK_CONST_METHOD0(isCurrent, bool());
+ MOCK_METHOD1(setCurrentSurface, bool(const renderengine::Surface&));
+ MOCK_METHOD0(resetCurrentSurface, void());
MOCK_METHOD0(flush, base::unique_fd());
MOCK_METHOD0(finish, bool());
MOCK_METHOD1(waitFence, bool(base::unique_fd*));
@@ -78,6 +82,23 @@
ANativeWindowBuffer* const, base::unique_fd*));
};
+class Surface : public renderengine::Surface {
+public:
+ Surface();
+ ~Surface() override;
+
+ MOCK_METHOD1(setCritical, void(bool));
+ MOCK_METHOD1(setAsync, void(bool));
+ MOCK_METHOD1(setNativeWindow, void(ANativeWindow*));
+ MOCK_CONST_METHOD0(swapBuffers, void());
+ MOCK_CONST_METHOD0(queryRedSize, int32_t());
+ MOCK_CONST_METHOD0(queryGreenSize, int32_t());
+ MOCK_CONST_METHOD0(queryBlueSize, int32_t());
+ MOCK_CONST_METHOD0(queryAlphaSize, int32_t());
+ MOCK_CONST_METHOD0(getWidth, int32_t());
+ MOCK_CONST_METHOD0(getHeight, int32_t());
+};
+
class Image : public renderengine::Image {
public:
Image();
diff --git a/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h b/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
index 4950a4b..561fd58 100644
--- a/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
+++ b/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
@@ -36,7 +36,6 @@
MOCK_METHOD1(queueBuffer_DEPRECATED, int(struct ANativeWindowBuffer*));
MOCK_CONST_METHOD2(query, int(int, int*));
MOCK_METHOD1(perform, int(int));
- MOCK_METHOD2(perform, int(int, int));
MOCK_METHOD1(cancelBuffer_DEPRECATED, int(struct ANativeWindowBuffer*));
MOCK_METHOD2(dequeueBuffer, int(struct ANativeWindowBuffer**, int*));
MOCK_METHOD2(queueBuffer, int(struct ANativeWindowBuffer*, int));