Change setScissor() to take in Vulkan coordinate convention.
* Cache dimensions in GLSurface and GLFramebuffer so that we don't have
to query properties through gl.
* Change argument to const Rect&
Bug: 114439058
Change-Id: Ia5ba9405af92819152e26e13508e0b57bc73f233
Test: SurfaceFlinger_Test, go/wm-smoke
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index e72aaca..744bdba 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -46,6 +46,7 @@
"libhwbinder",
"liblayers_proto",
"liblog",
+ "libnativewindow",
"libpdx_default_transport",
"libprotobuf-cpp-lite",
"libsync",
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 3eb0a92..4becfab 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -543,8 +543,8 @@
ANativeWindow* const window = mNativeWindow.get();
mSurface->setNativeWindow(window);
- mDisplayWidth = mSurface->queryWidth();
- mDisplayHeight = mSurface->queryHeight();
+ mDisplayWidth = mSurface->getWidth();
+ mDisplayHeight = mSurface->getHeight();
LOG_FATAL_IF(mDisplayWidth != newWidth,
"Unable to set new width to %d", newWidth);
diff --git a/services/surfaceflinger/RenderEngine/Android.bp b/services/surfaceflinger/RenderEngine/Android.bp
index e1ab066..79145c2 100644
--- a/services/surfaceflinger/RenderEngine/Android.bp
+++ b/services/surfaceflinger/RenderEngine/Android.bp
@@ -26,6 +26,7 @@
"libGLESv2",
"libgui",
"liblog",
+ "libnativewindow",
"libui",
"libutils",
],
diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
index 0f0ff62..5c929a3 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
@@ -444,12 +444,17 @@
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() {
@@ -563,8 +568,12 @@
drawMesh(mesh);
}
-void GLES20RenderEngine::setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) {
- glScissor(left, bottom, right, top);
+void GLES20RenderEngine::setScissor(const Rect& region) {
+ // Invert y-coordinate to map to GL-space.
+ int32_t canvasHeight = mRenderToFbo ? mFboHeight : mSurfaceHeight;
+ int32_t glBottom = canvasHeight - region.bottom;
+
+ glScissor(region.left, glBottom, region.getWidth(), region.getHeight());
glEnable(GL_SCISSOR_TEST);
}
@@ -612,6 +621,7 @@
GL_TEXTURE_2D, textureName, 0);
mRenderToFbo = true;
+ mFboHeight = glFramebuffer->getBufferHeight();
uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -623,13 +633,14 @@
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(0, 0, 0, 0);
+ setScissor(Rect::EMPTY_RECT);
clearWithColor(0.0, 0.0, 0.0, 0.0);
disableScissor();
}
diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
index 1abc5ba..e5086c4 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
@@ -64,7 +64,7 @@
void clearWithColor(float red, float green, float blue, float alpha) override;
void fillRegionWithColor(const Region& region, float red, float green, float blue,
float alpha) override;
- void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) override;
+ void setScissor(const Rect& region) override;
void disableScissor() override;
void genTextures(size_t count, uint32_t* names) override;
void deleteTextures(size_t count, uint32_t const* names) override;
@@ -139,6 +139,8 @@
mat4 mXyzToBt2020;
bool mRenderToFbo = false;
+ int32_t mSurfaceHeight = 0;
+ int32_t mFboHeight = 0;
// Current dataspace of layer being rendered
ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN;
diff --git a/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.cpp b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.cpp
index 6aca1c8..83d2bde 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.cpp
+++ b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.cpp
@@ -20,6 +20,7 @@
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#include <nativebase/nativebase.h>
#include "GLES20RenderEngine.h"
namespace android {
@@ -43,6 +44,8 @@
if (mEGLImage != EGL_NO_IMAGE_KHR) {
eglDestroyImageKHR(mEGLDisplay, mEGLImage);
mEGLImage = EGL_NO_IMAGE_KHR;
+ mBufferWidth = 0;
+ mBufferHeight = 0;
}
if (nativeBuffer) {
@@ -52,6 +55,8 @@
if (mEGLImage == EGL_NO_IMAGE_KHR) {
return false;
}
+ mBufferWidth = nativeBuffer->width;
+ mBufferHeight = nativeBuffer->height;
}
return true;
}
diff --git a/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.h b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.h
index 90b2248..193cbdc 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.h
+++ b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.h
@@ -39,11 +39,16 @@
EGLImageKHR getEGLImage() const { return mEGLImage; }
uint32_t getTextureName() const { return mTextureName; }
uint32_t getFramebufferName() const { return mFramebufferName; }
+ int32_t getBufferHeight() const { return mBufferHeight; }
+ int32_t getBufferWidth() const { return mBufferWidth; }
private:
EGLDisplay mEGLDisplay;
EGLImageKHR mEGLImage;
uint32_t mTextureName, mFramebufferName;
+
+ int32_t mBufferHeight = 0;
+ int32_t mBufferWidth = 0;
};
} // namespace gl
diff --git a/services/surfaceflinger/RenderEngine/gl/GLSurface.cpp b/services/surfaceflinger/RenderEngine/gl/GLSurface.cpp
index ff9a252..104af56 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLSurface.cpp
+++ b/services/surfaceflinger/RenderEngine/gl/GLSurface.cpp
@@ -16,6 +16,7 @@
#include "GLSurface.h"
+#include <android/native_window.h>
#include <log/log.h>
#include <ui/PixelFormat.h>
#include "GLES20RenderEngine.h"
@@ -41,11 +42,15 @@
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);
}
}
@@ -71,15 +76,6 @@
return value;
}
-EGLint GLSurface::querySurface(EGLint attrib) const {
- EGLint value;
- if (!eglQuerySurface(mEGLDisplay, mEGLSurface, attrib, &value)) {
- value = 0;
- }
-
- return value;
-}
-
int32_t GLSurface::queryRedSize() const {
return queryConfig(EGL_RED_SIZE);
}
@@ -96,12 +92,12 @@
return queryConfig(EGL_ALPHA_SIZE);
}
-int32_t GLSurface::queryWidth() const {
- return querySurface(EGL_WIDTH);
+int32_t GLSurface::getWidth() const {
+ return mSurfaceWidth;
}
-int32_t GLSurface::queryHeight() const {
- return querySurface(EGL_HEIGHT);
+int32_t GLSurface::getHeight() const {
+ return mSurfaceHeight;
}
} // namespace gl
diff --git a/services/surfaceflinger/RenderEngine/gl/GLSurface.h b/services/surfaceflinger/RenderEngine/gl/GLSurface.h
index 0b89c70..8aa223a 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLSurface.h
+++ b/services/surfaceflinger/RenderEngine/gl/GLSurface.h
@@ -47,15 +47,14 @@
int32_t queryBlueSize() const override;
int32_t queryAlphaSize() const override;
- int32_t queryWidth() const override;
- int32_t queryHeight() 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;
- EGLint querySurface(EGLint attrib) const;
EGLDisplay mEGLDisplay;
EGLConfig mEGLConfig;
@@ -63,6 +62,9 @@
bool mCritical = false;
bool mAsync = false;
+ int32_t mSurfaceWidth = 0;
+ int32_t mSurfaceHeight = 0;
+
ANativeWindow* mWindow = nullptr;
EGLSurface mEGLSurface = EGL_NO_SURFACE;
diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
index 17d8782..feceba8 100644
--- a/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
@@ -96,7 +96,7 @@
virtual void fillRegionWithColor(const Region& region, float red, float green,
float blue, float alpha) = 0;
- virtual void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) = 0;
+ virtual void setScissor(const Rect& region) = 0;
virtual void disableScissor() = 0;
virtual void genTextures(size_t count, uint32_t* names) = 0;
virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/Surface.h b/services/surfaceflinger/RenderEngine/include/renderengine/Surface.h
index 3343e1f..3999ddc 100644
--- a/services/surfaceflinger/RenderEngine/include/renderengine/Surface.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/Surface.h
@@ -38,8 +38,8 @@
virtual int32_t queryBlueSize() const = 0;
virtual int32_t queryAlphaSize() const = 0;
- virtual int32_t queryWidth() const = 0;
- virtual int32_t queryHeight() const = 0;
+ virtual int32_t getWidth() const = 0;
+ virtual int32_t getHeight() const = 0;
};
} // namespace renderengine
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f17710e..506099f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2493,8 +2493,8 @@
renderSurface->setCritical(state.type == DisplayDevice::DISPLAY_PRIMARY);
renderSurface->setAsync(state.isVirtual());
renderSurface->setNativeWindow(nativeWindow.get());
- const int displayWidth = renderSurface->queryWidth();
- const int displayHeight = renderSurface->queryHeight();
+ const int displayWidth = renderSurface->getWidth();
+ const int displayHeight = renderSurface->getHeight();
// 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
@@ -3205,9 +3205,7 @@
// the GL scissor so we don't draw anything where we shouldn't
// enable scissor for this frame
- const uint32_t height = display->getHeight();
- getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
- scissor.getWidth(), scissor.getHeight());
+ getBE().mRenderEngine->setScissor(scissor);
}
}
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index aa377af..cc46043 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -284,8 +284,8 @@
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);
- EXPECT_CALL(*test->mRenderSurface, queryWidth()).WillOnce(Return(WIDTH));
- EXPECT_CALL(*test->mRenderSurface, queryHeight()).WillOnce(Return(HEIGHT));
+ EXPECT_CALL(*test->mRenderSurface, getWidth()).WillOnce(Return(WIDTH));
+ EXPECT_CALL(*test->mRenderSurface, getHeight()).WillOnce(Return(HEIGHT));
}
static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
@@ -1757,8 +1757,8 @@
EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
- EXPECT_CALL(*renderSurface, queryWidth()).WillOnce(Return(newWidth));
- EXPECT_CALL(*renderSurface, queryHeight()).WillOnce(Return(oldHeight));
+ EXPECT_CALL(*renderSurface, getWidth()).WillOnce(Return(newWidth));
+ EXPECT_CALL(*renderSurface, getHeight()).WillOnce(Return(oldHeight));
// --------------------------------------------------------------------
// Invocation
@@ -1798,8 +1798,8 @@
EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
- EXPECT_CALL(*renderSurface, queryWidth()).WillOnce(Return(oldWidth));
- EXPECT_CALL(*renderSurface, queryHeight()).WillOnce(Return(newHeight));
+ EXPECT_CALL(*renderSurface, getWidth()).WillOnce(Return(oldWidth));
+ EXPECT_CALL(*renderSurface, getHeight()).WillOnce(Return(newHeight));
// --------------------------------------------------------------------
// Invocation
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 39ed622..649e949 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -50,7 +50,7 @@
bool waitFence(base::unique_fd fd) override { return waitFence(&fd); };
MOCK_METHOD4(clearWithColor, void(float, float, float, float));
MOCK_METHOD5(fillRegionWithColor, void(const Region&, float, float, float, float));
- MOCK_METHOD4(setScissor, void(uint32_t, uint32_t, uint32_t, uint32_t));
+ MOCK_METHOD1(setScissor, void(const Rect&));
MOCK_METHOD0(disableScissor, void());
MOCK_METHOD2(genTextures, void(size_t, uint32_t*));
MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*));
@@ -91,8 +91,8 @@
MOCK_CONST_METHOD0(queryGreenSize, int32_t());
MOCK_CONST_METHOD0(queryBlueSize, int32_t());
MOCK_CONST_METHOD0(queryAlphaSize, int32_t());
- MOCK_CONST_METHOD0(queryWidth, int32_t());
- MOCK_CONST_METHOD0(queryHeight, int32_t());
+ MOCK_CONST_METHOD0(getWidth, int32_t());
+ MOCK_CONST_METHOD0(getHeight, int32_t());
};
class Image : public renderengine::Image {