Merge changes from topic "sf-re"
* changes:
surfaceflinger: run clang-format on RenderEngine
surfaceflinger: remove all direct use of EGL
surfaceflinger: use RE::Surface in DisplayDevice
surfaceflinger: add surface abstraction to RE
surfaceflinger: remove DisplayDevice::swapRegion
surfaceflinger: remove DisplayDevice::mFlags
surfaceflinger: remove unused EGL data members
surfaceflinger: remove EGLConfig from DisplayDevice ctor
surfaceflinger: add RenderEngine::BindNativeBufferAsFramebuffer
surfaceflinger: return fence fd from RenderEngine::flush
surfaceflinger: add RenderEngine::setCurrentSurface
surfaceflinger: move EGL version/extensions dump into RE
surfaceflinger: move EGL termination into RE
surfaceflinger: move EGL initialization into RE
surfaceflinger: add RenderEngine::mEGLDisplay
surfaceflinger: manage RenderEngine with unique_ptr
diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
index e9fc8fd..4a86021 100644
--- a/libs/gui/include/gui/ConsumerBase.h
+++ b/libs/gui/include/gui/ConsumerBase.h
@@ -187,7 +187,7 @@
// ConsumerBase::releaseBufferLocked.
virtual status_t releaseBufferLocked(int slot,
const sp<GraphicBuffer> graphicBuffer,
- EGLDisplay display, EGLSyncKHR eglFence);
+ EGLDisplay display = EGL_NO_DISPLAY, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR);
// returns true iff the slot still has the graphicBuffer in it.
bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer);
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index ecee8ce..deead06 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -41,6 +41,7 @@
RenderEngine/ProgramCache.cpp \
RenderEngine/GLExtensions.cpp \
RenderEngine/RenderEngine.cpp \
+ RenderEngine/Surface.cpp \
RenderEngine/Texture.cpp \
RenderEngine/GLES20RenderEngine.cpp \
LayerProtoHelper.cpp \
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 078302b..1127952 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -32,9 +32,6 @@
#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
#include <ui/FrameStats.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 6d6781e..2753f11 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -53,12 +53,6 @@
using namespace android;
// ----------------------------------------------------------------------------
-#ifdef EGL_ANDROID_swap_rectangle
-static constexpr bool kEGLAndroidSwapRectangle = true;
-#else
-static constexpr bool kEGLAndroidSwapRectangle = false;
-#endif
-
// retrieve triple buffer setting from configstore
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
@@ -66,12 +60,6 @@
static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) >= 3;
-#if !defined(EGL_EGLEXT_PROTOTYPES) || !defined(EGL_ANDROID_swap_rectangle)
-// Dummy implementation in case it is missing.
-inline void eglSetSwapRectangleANDROID (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) {
-}
-#endif
-
/*
* Initialize the display to the specified values.
*
@@ -88,7 +76,6 @@
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer,
- EGLConfig config,
bool supportWideColor)
: lastCompositionHadVisibleLayers(false),
mFlinger(flinger),
@@ -96,11 +83,9 @@
mHwcDisplayId(hwcId),
mDisplayToken(displayToken),
mDisplaySurface(displaySurface),
- mDisplay(EGL_NO_DISPLAY),
- mSurface(EGL_NO_SURFACE),
+ mSurface{flinger->getRenderEngine()},
mDisplayWidth(),
mDisplayHeight(),
- mFlags(),
mPageFlipCount(),
mIsSecure(isSecure),
mLayerStack(NO_LAYER_STACK),
@@ -118,16 +103,11 @@
/*
* Create our display's surface
*/
-
- EGLSurface eglSurface;
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (config == EGL_NO_CONFIG) {
- config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888,
- /*logConfig*/ false);
- }
- eglSurface = eglCreateWindowSurface(display, config, window, NULL);
- eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth);
- eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);
+ mSurface.setCritical(mType == DisplayDevice::DISPLAY_PRIMARY);
+ mSurface.setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL);
+ mSurface.setNativeWindow(window);
+ mDisplayWidth = mSurface.queryWidth();
+ mDisplayHeight = mSurface.queryHeight();
// 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
@@ -139,9 +119,6 @@
if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
window->setSwapInterval(window, 0);
- mConfig = config;
- mDisplay = display;
- mSurface = eglSurface;
mPageFlipCount = 0;
mViewport.makeInvalid();
mFrame.makeInvalid();
@@ -173,10 +150,6 @@
}
DisplayDevice::~DisplayDevice() {
- if (mSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mDisplay, mSurface);
- mSurface = EGL_NO_SURFACE;
- }
}
void DisplayDevice::disconnect(HWComposer& hwc) {
@@ -198,10 +171,6 @@
return mDisplayHeight;
}
-EGLSurface DisplayDevice::getEGLSurface() const {
- return mSurface;
-}
-
void DisplayDevice::setDisplayName(const String8& displayName) {
if (!displayName.isEmpty()) {
// never override the name with an empty name
@@ -213,19 +182,9 @@
return mPageFlipCount;
}
-void DisplayDevice::flip(const Region& dirty) const
+void DisplayDevice::flip() const
{
mFlinger->getRenderEngine().checkErrors();
-
- if (kEGLAndroidSwapRectangle) {
- if (mFlags & SWAP_RECTANGLE) {
- const Region newDirty(dirty.intersect(bounds()));
- const Rect b(newDirty.getBounds());
- eglSetSwapRectangleANDROID(mDisplay, mSurface,
- b.left, b.top, b.width(), b.height());
- }
- }
-
mPageFlipCount++;
}
@@ -259,18 +218,7 @@
void DisplayDevice::swapBuffers(HWComposer& hwc) const {
if (hwc.hasClientComposition(mHwcDisplayId)) {
- EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
- if (!success) {
- EGLint error = eglGetError();
- if (error == EGL_CONTEXT_LOST ||
- mType == DisplayDevice::DISPLAY_PRIMARY) {
- LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
- mDisplay, mSurface, error);
- } else {
- ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
- mDisplay, mSurface, error);
- }
- }
+ mSurface.swapBuffers();
}
status_t result = mDisplaySurface->advanceFrame();
@@ -284,23 +232,10 @@
mDisplaySurface->onFrameCommitted();
}
-uint32_t DisplayDevice::getFlags() const
-{
- return mFlags;
-}
-
-EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
- EGLBoolean result = EGL_TRUE;
- EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
- if (sur != mSurface) {
- result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
- if (result == EGL_TRUE) {
- if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
- eglSwapInterval(dpy, 0);
- }
- }
+bool DisplayDevice::makeCurrent() const {
+ bool success = mFlinger->getRenderEngine().setCurrentSurface(mSurface);
setViewportAndProjection();
- return result;
+ return success;
}
void DisplayDevice::setViewportAndProjection() const {
@@ -436,17 +371,14 @@
void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
dirtyRegion.set(getBounds());
- if (mSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mDisplay, mSurface);
- mSurface = EGL_NO_SURFACE;
- }
+ mSurface.setNativeWindow(nullptr);
mDisplaySurface->resizeBuffers(newWidth, newHeight);
ANativeWindow* const window = mNativeWindow.get();
- mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
- eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth);
- eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
+ mSurface.setNativeWindow(window);
+ mDisplayWidth = mSurface.queryWidth();
+ mDisplayHeight = mSurface.queryHeight();
LOG_FATAL_IF(mDisplayWidth != newWidth,
"Unable to set new width to %d", newWidth);
@@ -548,17 +480,13 @@
void DisplayDevice::dump(String8& result) const {
const Transform& tr(mGlobalTransform);
ANativeWindow* const window = mNativeWindow.get();
- EGLint redSize, greenSize, blueSize, alphaSize;
- eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &redSize);
- eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &greenSize);
- eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &blueSize);
- eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &alphaSize);
result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string());
result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p "
"(%d:%d:%d:%d), orient=%2d (type=%08x), "
"flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, window,
- redSize, greenSize, blueSize, alphaSize, mOrientation, tr.getType(),
+ 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],"
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index e388a5b..499bf8e 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -23,9 +23,6 @@
#include <ui/Region.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
#include <binder/IBinder.h>
#include <utils/RefBase.h>
#include <utils/Mutex.h>
@@ -35,6 +32,7 @@
#include <gui/ISurfaceComposer.h>
#include <hardware/hwcomposer_defs.h>
#include "RenderArea.h"
+#include "RenderEngine/Surface.h"
#include <memory>
@@ -56,8 +54,6 @@
// region in layer-stack space
mutable Region dirtyRegion;
// region in screen space
- mutable Region swapRegion;
- // region in screen space
Region undefinedRegion;
bool lastCompositionHadVisibleLayers;
@@ -70,11 +66,6 @@
};
enum {
- PARTIAL_UPDATES = 0x00020000, // video driver feature
- SWAP_RECTANGLE = 0x00080000,
- };
-
- enum {
NO_LAYER_STACK = 0xFFFFFFFF,
};
@@ -87,7 +78,6 @@
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer,
- EGLConfig config,
bool supportWideColor);
// clang-format on
@@ -103,13 +93,10 @@
// Flip the front and back buffers if the back buffer is "dirty". Might
// be instantaneous, might involve copying the frame buffer around.
- void flip(const Region& dirty) const;
+ void flip() const;
int getWidth() const;
int getHeight() const;
- uint32_t getFlags() const;
-
- EGLSurface getEGLSurface() const;
void setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers);
const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const;
@@ -155,7 +142,7 @@
void setDisplayName(const String8& displayName);
const String8& getDisplayName() const { return mDisplayName; }
- EGLBoolean makeCurrent(EGLDisplay dpy, EGLContext ctx) const;
+ bool makeCurrent() const;
void setViewportAndProjection() const;
const sp<Fence>& getClientTargetAcquireFence() const;
@@ -199,12 +186,9 @@
sp<ANativeWindow> mNativeWindow;
sp<DisplaySurface> mDisplaySurface;
- EGLConfig mConfig;
- EGLDisplay mDisplay;
- EGLSurface mSurface;
+ RE::Surface mSurface;
int mDisplayWidth;
int mDisplayHeight;
- uint32_t mFlags;
mutable uint32_t mPageFlipCount;
String8 mDisplayName;
bool mIsSecure;
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 182629c..8b5d4c9 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -27,8 +27,6 @@
#include <utils/String8.h>
#include <log/log.h>
-#include <EGL/egl.h>
-
#include <hardware/hardware.h>
#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
@@ -164,8 +162,7 @@
ALOGE_IF(result != NO_ERROR, "onFrameCommitted: failed to add the"
" fence: %s (%d)", strerror(-result), result);
}
- status_t result = releaseBufferLocked(mPreviousBufferSlot,
- mPreviousBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+ status_t result = releaseBufferLocked(mPreviousBufferSlot, mPreviousBuffer);
ALOGE_IF(result != NO_ERROR, "onFrameCommitted: error releasing buffer:"
" %s (%d)", strerror(-result), result);
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index dba6f7c..cde96e4 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -244,8 +244,7 @@
VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot);
addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot],
retireFence);
- releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot],
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+ releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot]);
}
if (mOutputProducerSlot >= 0) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index b7b7a3a..b12e34f 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -20,9 +20,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/Timers.h>
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index 706960c..e014406 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -33,8 +33,7 @@
mColorMatrixEnabled = false;
}
-Description::~Description() {
-}
+Description::~Description() {}
void Description::setPremultipliedAlpha(bool premultipliedAlpha) {
mPremultipliedAlpha = premultipliedAlpha;
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 3ae7042..3161888 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -33,15 +33,15 @@
#include <gui/ISurfaceComposer.h>
#include <math.h>
+#include "Description.h"
#include "GLES20RenderEngine.h"
+#include "Mesh.h"
#include "Program.h"
#include "ProgramCache.h"
-#include "Description.h"
-#include "Mesh.h"
#include "Texture.h"
-#include <sstream>
#include <fstream>
+#include <sstream>
// ---------------------------------------------------------------------------
bool checkGlError(const char* op, int lineNumber) {
@@ -107,34 +107,31 @@
namespace android {
// ---------------------------------------------------------------------------
-GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags) :
- mVpWidth(0),
- mVpHeight(0),
- mPlatformHasWideColor((featureFlags & WIDE_COLOR_SUPPORT) != 0) {
-
+GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags)
+ : mVpWidth(0), mVpHeight(0), mPlatformHasWideColor((featureFlags & WIDE_COLOR_SUPPORT) != 0) {
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
- const uint16_t protTexData[] = { 0 };
+ const uint16_t protTexData[] = {0};
glGenTextures(1, &mProtectedTexName);
glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
- //mColorBlindnessCorrection = M;
+ // mColorBlindnessCorrection = M;
if (mPlatformHasWideColor) {
// Compute sRGB to DisplayP3 color transform
// NOTE: For now, we are limiting wide-color support to
// Display-P3 only.
- mat3 srgbToP3 = ColorSpaceConnector(ColorSpace::sRGB(), ColorSpace::DisplayP3()).getTransform();
+ mat3 srgbToP3 =
+ ColorSpaceConnector(ColorSpace::sRGB(), ColorSpace::DisplayP3()).getTransform();
// color transform needs to be expanded to 4x4 to be what the shader wants
// mat has an initializer that expands mat3 to mat4, but
@@ -144,24 +141,19 @@
}
}
-GLES20RenderEngine::~GLES20RenderEngine() {
-}
-
+GLES20RenderEngine::~GLES20RenderEngine() {}
size_t GLES20RenderEngine::getMaxTextureSize() const {
return mMaxTextureSize;
}
size_t GLES20RenderEngine::getMaxViewportDims() const {
- return
- mMaxViewportDims[0] < mMaxViewportDims[1] ?
- mMaxViewportDims[0] : mMaxViewportDims[1];
+ return mMaxViewportDims[0] < mMaxViewportDims[1] ? mMaxViewportDims[0] : mMaxViewportDims[1];
}
-void GLES20RenderEngine::setViewportAndProjection(
- size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
- Transform::orientation_flags rotation) {
-
+void GLES20RenderEngine::setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
+ size_t hwh, bool yswap,
+ Transform::orientation_flags rotation) {
size_t l = sourceCrop.left;
size_t r = sourceCrop.right;
@@ -182,13 +174,13 @@
case Transform::ROT_0:
break;
case Transform::ROT_90:
- m = mat4::rotate(rot90InRadians, vec3(0,0,1)) * m;
+ m = mat4::rotate(rot90InRadians, vec3(0, 0, 1)) * m;
break;
case Transform::ROT_180:
- m = mat4::rotate(rot90InRadians * 2.0f, vec3(0,0,1)) * m;
+ m = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1)) * m;
break;
case Transform::ROT_270:
- m = mat4::rotate(rot90InRadians * 3.0f, vec3(0,0,1)) * m;
+ m = mat4::rotate(rot90InRadians * 3.0f, vec3(0, 0, 1)) * m;
break;
default:
break;
@@ -200,8 +192,8 @@
mVpHeight = vph;
}
-void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha,
- bool opaque, bool disableTexture, const half4& color) {
+void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha, bool opaque,
+ bool disableTexture, const half4& color) {
mState.setPremultipliedAlpha(premultipliedAlpha);
mState.setOpaque(opaque);
mState.setColor(color);
@@ -288,9 +280,8 @@
glDisable(GL_BLEND);
}
-
-void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName,
+ uint32_t* fbName, uint32_t* status) {
GLuint tname, name;
// turn our EGLImage into a texture
glGenTextures(1, &tname);
@@ -322,21 +313,14 @@
}
void GLES20RenderEngine::drawMesh(const Mesh& mesh) {
-
if (mesh.getTexCoordsSize()) {
glEnableVertexAttribArray(Program::texCoords);
- glVertexAttribPointer(Program::texCoords,
- mesh.getTexCoordsSize(),
- GL_FLOAT, GL_FALSE,
- mesh.getByteStride(),
- mesh.getTexCoords());
+ glVertexAttribPointer(Program::texCoords, mesh.getTexCoordsSize(), GL_FLOAT, GL_FALSE,
+ mesh.getByteStride(), mesh.getTexCoords());
}
- glVertexAttribPointer(Program::position,
- mesh.getVertexSize(),
- GL_FLOAT, GL_FALSE,
- mesh.getByteStride(),
- mesh.getPositions());
+ glVertexAttribPointer(Program::position, mesh.getVertexSize(), GL_FLOAT, GL_FALSE,
+ mesh.getByteStride(), mesh.getPositions());
if (usesWideColor()) {
Description wideColorState = mState;
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index b96bfe0..5ee9326 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
#ifndef SF_GLES20RENDERENGINE_H_
#define SF_GLES20RENDERENGINE_H_
@@ -24,9 +23,9 @@
#include <GLES2/gl2.h>
#include <Transform.h>
-#include "RenderEngine.h"
-#include "ProgramCache.h"
#include "Description.h"
+#include "ProgramCache.h"
+#include "RenderEngine.h"
// ---------------------------------------------------------------------------
namespace android {
@@ -54,22 +53,20 @@
Description mState;
Vector<Group> mGroupStack;
- virtual void bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status);
+ virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName,
+ uint32_t* status);
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
public:
GLES20RenderEngine(uint32_t featureFlags); // See RenderEngine::FeatureFlag
-
-protected:
virtual ~GLES20RenderEngine();
+protected:
virtual void dump(String8& result);
- virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap,
- Transform::orientation_flags rotation);
- virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
- bool disableTexture, const half4& color) override;
+ virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop, size_t hwh,
+ bool yswap, Transform::orientation_flags rotation);
+ virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
+ const half4& color) override;
// Color management related functions and state
void setColorMode(android_color_mode mode);
diff --git a/services/surfaceflinger/RenderEngine/GLExtensions.cpp b/services/surfaceflinger/RenderEngine/GLExtensions.cpp
index 76bbcc1..7ffcc96 100644
--- a/services/surfaceflinger/RenderEngine/GLExtensions.cpp
+++ b/services/surfaceflinger/RenderEngine/GLExtensions.cpp
@@ -14,42 +14,35 @@
* limitations under the License.
*/
-#include <stdlib.h>
-#include <stdio.h>
#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#include "GLExtensions.h"
namespace android {
// ---------------------------------------------------------------------------
-ANDROID_SINGLETON_STATIC_INSTANCE( GLExtensions )
+ANDROID_SINGLETON_STATIC_INSTANCE(GLExtensions)
-GLExtensions::GLExtensions()
- : mHaveFramebufferObject(false)
-{
-}
+GLExtensions::GLExtensions() : mHaveFramebufferObject(false) {}
-void GLExtensions::initWithGLStrings(
- GLubyte const* vendor,
- GLubyte const* renderer,
- GLubyte const* version,
- GLubyte const* extensions)
-{
- mVendor = (char const*)vendor;
- mRenderer = (char const*)renderer;
- mVersion = (char const*)version;
+void GLExtensions::initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer,
+ GLubyte const* version, GLubyte const* extensions) {
+ mVendor = (char const*)vendor;
+ mRenderer = (char const*)renderer;
+ mVersion = (char const*)version;
mExtensions = (char const*)extensions;
char const* curr = (char const*)extensions;
char const* head = curr;
do {
head = strchr(curr, ' ');
- String8 s(curr, head ? head-curr : strlen(curr));
+ String8 s(curr, head ? head - curr : strlen(curr));
if (s.length()) {
mExtensionList.add(s);
}
- curr = head+1;
+ curr = head + 1;
} while (head);
if (hasExtension("GL_OES_framebuffer_object")) {
@@ -57,8 +50,7 @@
}
}
-bool GLExtensions::hasExtension(char const* extension) const
-{
+bool GLExtensions::hasExtension(char const* extension) const {
const String8 s(extension);
return mExtensionList.indexOf(s) >= 0;
}
diff --git a/services/surfaceflinger/RenderEngine/GLExtensions.h b/services/surfaceflinger/RenderEngine/GLExtensions.h
index d81ed2a..ee7b446 100644
--- a/services/surfaceflinger/RenderEngine/GLExtensions.h
+++ b/services/surfaceflinger/RenderEngine/GLExtensions.h
@@ -20,9 +20,9 @@
#include <stdint.h>
#include <sys/types.h>
-#include <utils/String8.h>
-#include <utils/SortedVector.h>
#include <utils/Singleton.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -32,8 +32,7 @@
namespace android {
// ---------------------------------------------------------------------------
-class GLExtensions : public Singleton<GLExtensions>
-{
+class GLExtensions : public Singleton<GLExtensions> {
friend class Singleton<GLExtensions>;
bool mHaveFramebufferObject : 1;
@@ -45,22 +44,16 @@
SortedVector<String8> mExtensionList;
GLExtensions(const GLExtensions&);
- GLExtensions& operator = (const GLExtensions&);
+ GLExtensions& operator=(const GLExtensions&);
protected:
GLExtensions();
public:
+ inline bool haveFramebufferObject() const { return mHaveFramebufferObject; }
- inline bool haveFramebufferObject() const {
- return mHaveFramebufferObject;
- }
-
- void initWithGLStrings(
- GLubyte const* vendor,
- GLubyte const* renderer,
- GLubyte const* version,
- GLubyte const* extensions);
+ void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version,
+ GLubyte const* extensions);
char const* getVendor() const;
char const* getRenderer() const;
@@ -70,7 +63,6 @@
bool hasExtension(char const* extension) const;
};
-
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/RenderEngine/Mesh.cpp b/services/surfaceflinger/RenderEngine/Mesh.cpp
index ffd9be2..6a62b1d 100644
--- a/services/surfaceflinger/RenderEngine/Mesh.cpp
+++ b/services/surfaceflinger/RenderEngine/Mesh.cpp
@@ -21,9 +21,10 @@
namespace android {
Mesh::Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize)
- : mVertexCount(vertexCount), mVertexSize(vertexSize), mTexCoordsSize(texCoordSize),
- mPrimitive(primitive)
-{
+ : mVertexCount(vertexCount),
+ mVertexSize(vertexSize),
+ mTexCoordsSize(texCoordSize),
+ mPrimitive(primitive) {
if (vertexCount == 0) {
mVertices = new float[1];
mVertices[0] = 0.0f;
@@ -37,8 +38,7 @@
// either vertexSize or texCoordSize, it must have overflowed. remainder
// will be equal to stride as long as stride * vertexCount doesn't overflow.
if ((stride < vertexSize) || (remainder != stride)) {
- ALOGE("Overflow in Mesh(..., %zu, %zu, %zu)", vertexCount, vertexSize,
- texCoordSize);
+ ALOGE("Overflow in Mesh(..., %zu, %zu, %zu)", vertexCount, vertexSize, texCoordSize);
mVertices = new float[1];
mVertices[0] = 0.0f;
mVertexCount = 0;
@@ -53,14 +53,13 @@
}
Mesh::~Mesh() {
- delete [] mVertices;
+ delete[] mVertices;
}
Mesh::Primitive Mesh::getPrimitive() const {
return mPrimitive;
}
-
float const* Mesh::getPositions() const {
return mVertices;
}
@@ -75,7 +74,6 @@
return mVertices + mVertexSize;
}
-
size_t Mesh::getVertexCount() const {
return mVertexCount;
}
@@ -89,7 +87,7 @@
}
size_t Mesh::getByteStride() const {
- return mStride*sizeof(float);
+ return mStride * sizeof(float);
}
size_t Mesh::getStride() const {
diff --git a/services/surfaceflinger/RenderEngine/Mesh.h b/services/surfaceflinger/RenderEngine/Mesh.h
index b6d42b0..d0a9ac0 100644
--- a/services/surfaceflinger/RenderEngine/Mesh.h
+++ b/services/surfaceflinger/RenderEngine/Mesh.h
@@ -24,9 +24,9 @@
class Mesh {
public:
enum Primitive {
- TRIANGLES = 0x0004, // GL_TRIANGLES
- TRIANGLE_STRIP = 0x0005, // GL_TRIANGLE_STRIP
- TRIANGLE_FAN = 0x0006 // GL_TRIANGLE_FAN
+ TRIANGLES = 0x0004, // GL_TRIANGLES
+ TRIANGLE_STRIP = 0x0005, // GL_TRIANGLE_STRIP
+ TRIANGLE_FAN = 0x0006 // GL_TRIANGLE_FAN
};
Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordsSize = 0);
@@ -40,21 +40,24 @@
friend class Mesh;
float* mData;
size_t mStride;
- VertexArray(float* data, size_t stride) : mData(data), mStride(stride) { }
+ VertexArray(float* data, size_t stride) : mData(data), mStride(stride) {}
+
public:
- TYPE& operator[](size_t index) {
- return *reinterpret_cast<TYPE*>(&mData[index*mStride]);
- }
+ TYPE& operator[](size_t index) { return *reinterpret_cast<TYPE*>(&mData[index * mStride]); }
TYPE const& operator[](size_t index) const {
- return *reinterpret_cast<TYPE const*>(&mData[index*mStride]);
+ return *reinterpret_cast<TYPE const*>(&mData[index * mStride]);
}
};
template <typename TYPE>
- VertexArray<TYPE> getPositionArray() { return VertexArray<TYPE>(getPositions(), mStride); }
+ VertexArray<TYPE> getPositionArray() {
+ return VertexArray<TYPE>(getPositions(), mStride);
+ }
template <typename TYPE>
- VertexArray<TYPE> getTexCoordArray() { return VertexArray<TYPE>(getTexCoords(), mStride); }
+ VertexArray<TYPE> getTexCoordArray() {
+ return VertexArray<TYPE>(getTexCoords(), mStride);
+ }
Primitive getPrimitive() const;
@@ -81,8 +84,8 @@
private:
Mesh(const Mesh&);
- Mesh& operator = (const Mesh&);
- Mesh const& operator = (const Mesh&) const;
+ Mesh& operator=(const Mesh&);
+ Mesh const& operator=(const Mesh&) const;
float* getPositions();
float* getTexCoords();
@@ -94,6 +97,5 @@
Primitive mPrimitive;
};
-
} /* namespace android */
#endif /* SF_RENDER_ENGINE_MESH_H */
diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp
index bd2188b..baf92eb 100644
--- a/services/surfaceflinger/RenderEngine/Program.cpp
+++ b/services/surfaceflinger/RenderEngine/Program.cpp
@@ -19,15 +19,15 @@
#include <log/log.h>
#include <utils/String8.h>
+#include <math/mat4.h>
+#include "Description.h"
#include "Program.h"
#include "ProgramCache.h"
-#include "Description.h"
-#include <math/mat4.h>
namespace android {
Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const char* fragment)
- : mInitialized(false) {
+ : mInitialized(false) {
GLuint vertexId = buildShader(vertex, GL_VERTEX_SHADER);
GLuint fragmentId = buildShader(fragment, GL_FRAGMENT_SHADER);
GLuint programId = glCreateProgram();
@@ -67,14 +67,12 @@
// set-up the default values for our uniforms
glUseProgram(programId);
- const GLfloat m[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
- glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, m);
+ glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, mat4().asArray());
glEnableVertexAttribArray(0);
}
}
-Program::~Program() {
-}
+Program::~Program() {}
bool Program::isValid() const {
return mInitialized;
@@ -119,12 +117,11 @@
char* src = new char[l];
glGetShaderSource(shader, l, NULL, src);
result.append(src);
- delete [] src;
+ delete[] src;
return result;
}
void Program::setUniforms(const Description& desc) {
-
// TODO: we should have a mechanism here to not always reset uniforms that
// didn't change for this program.
diff --git a/services/surfaceflinger/RenderEngine/Program.h b/services/surfaceflinger/RenderEngine/Program.h
index a2ae2ee..6e57fdd 100644
--- a/services/surfaceflinger/RenderEngine/Program.h
+++ b/services/surfaceflinger/RenderEngine/Program.h
@@ -34,7 +34,7 @@
class Program {
public:
// known locations for position and texture coordinates
- enum { position=0, texCoords=1 };
+ enum { position = 0, texCoords = 1 };
Program(const ProgramCache::Key& needs, const char* vertex, const char* fragment);
~Program();
@@ -54,7 +54,6 @@
/* set-up uniforms from the description */
void setUniforms(const Description& desc);
-
private:
GLuint buildShader(const char* source, GLenum type);
String8& dumpShader(String8& result, GLenum type);
@@ -83,7 +82,6 @@
GLint mColorLoc;
};
-
} /* namespace android */
#endif /* SF_RENDER_ENGINE_PROGRAM_H */
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index b437545..4f138dc 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -19,14 +19,13 @@
#include <utils/String8.h>
-#include "ProgramCache.h"
-#include "Program.h"
#include "Description.h"
+#include "Program.h"
+#include "ProgramCache.h"
namespace android {
// -----------------------------------------------------------------------------------------------
-
/*
* A simple formatter class to automatically add the endl and
* manage the indentation.
@@ -42,23 +41,22 @@
typedef Formatter& (*FormaterManipFunc)(Formatter&);
friend Formatter& indent(Formatter& f);
friend Formatter& dedent(Formatter& f);
+
public:
Formatter() : mIndent(0) {}
- String8 getString() const {
- return mString;
- }
+ String8 getString() const { return mString; }
- friend Formatter& operator << (Formatter& out, const char* in) {
- for (int i=0 ; i<out.mIndent ; i++) {
+ friend Formatter& operator<<(Formatter& out, const char* in) {
+ for (int i = 0; i < out.mIndent; i++) {
out.mString.append(" ");
}
out.mString.append(in);
out.mString.append("\n");
return out;
}
- friend inline Formatter& operator << (Formatter& out, const String8& in) {
- return operator << (out, in.string());
+ friend inline Formatter& operator<<(Formatter& out, const String8& in) {
+ return operator<<(out, in.string());
}
friend inline Formatter& operator<<(Formatter& to, FormaterManipFunc func) {
return (*func)(to);
@@ -83,13 +81,11 @@
primeCache();
}
-ProgramCache::~ProgramCache() {
-}
+ProgramCache::~ProgramCache() {}
void ProgramCache::primeCache() {
uint32_t shaderCount = 0;
- uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK |
- Key::ALPHA_MASK | Key::TEXTURE_MASK;
+ uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK | Key::ALPHA_MASK | Key::TEXTURE_MASK;
// Prime the cache for all combinations of the above masks,
// leaving off the experimental color matrix mask options.
@@ -98,9 +94,7 @@
Key shaderKey;
shaderKey.set(keyMask, keyVal);
uint32_t tex = shaderKey.getTextureTarget();
- if (tex != Key::TEXTURE_OFF &&
- tex != Key::TEXTURE_EXT &&
- tex != Key::TEXTURE_2D) {
+ if (tex != Key::TEXTURE_OFF && tex != Key::TEXTURE_EXT && tex != Key::TEXTURE_2D) {
continue;
}
Program* program = mCache.valueFor(shaderKey);
@@ -118,34 +112,36 @@
ProgramCache::Key ProgramCache::computeKey(const Description& description) {
Key needs;
needs.set(Key::TEXTURE_MASK,
- !description.mTextureEnabled ? Key::TEXTURE_OFF :
- description.mTexture.getTextureTarget() == GL_TEXTURE_EXTERNAL_OES ? Key::TEXTURE_EXT :
- description.mTexture.getTextureTarget() == GL_TEXTURE_2D ? Key::TEXTURE_2D :
- Key::TEXTURE_OFF)
- .set(Key::ALPHA_MASK,
- (description.mColor.a < 1) ? Key::ALPHA_LT_ONE : Key::ALPHA_EQ_ONE)
- .set(Key::BLEND_MASK,
- description.mPremultipliedAlpha ? Key::BLEND_PREMULT : Key::BLEND_NORMAL)
- .set(Key::OPACITY_MASK,
- description.mOpaque ? Key::OPACITY_OPAQUE : Key::OPACITY_TRANSLUCENT)
- .set(Key::COLOR_MATRIX_MASK,
- description.mColorMatrixEnabled ? Key::COLOR_MATRIX_ON : Key::COLOR_MATRIX_OFF)
- .set(Key::WIDE_GAMUT_MASK,
- description.mIsWideGamut ? Key::WIDE_GAMUT_ON : Key::WIDE_GAMUT_OFF);
+ !description.mTextureEnabled
+ ? Key::TEXTURE_OFF
+ : description.mTexture.getTextureTarget() == GL_TEXTURE_EXTERNAL_OES
+ ? Key::TEXTURE_EXT
+ : description.mTexture.getTextureTarget() == GL_TEXTURE_2D
+ ? Key::TEXTURE_2D
+ : Key::TEXTURE_OFF)
+ .set(Key::ALPHA_MASK,
+ (description.mColor.a < 1) ? Key::ALPHA_LT_ONE : Key::ALPHA_EQ_ONE)
+ .set(Key::BLEND_MASK,
+ description.mPremultipliedAlpha ? Key::BLEND_PREMULT : Key::BLEND_NORMAL)
+ .set(Key::OPACITY_MASK,
+ description.mOpaque ? Key::OPACITY_OPAQUE : Key::OPACITY_TRANSLUCENT)
+ .set(Key::COLOR_MATRIX_MASK,
+ description.mColorMatrixEnabled ? Key::COLOR_MATRIX_ON : Key::COLOR_MATRIX_OFF)
+ .set(Key::WIDE_GAMUT_MASK,
+ description.mIsWideGamut ? Key::WIDE_GAMUT_ON : Key::WIDE_GAMUT_OFF);
return needs;
}
String8 ProgramCache::generateVertexShader(const Key& needs) {
Formatter vs;
if (needs.isTexturing()) {
- vs << "attribute vec4 texCoords;"
- << "varying vec2 outTexCoords;";
+ vs << "attribute vec4 texCoords;"
+ << "varying vec2 outTexCoords;";
}
vs << "attribute vec4 position;"
<< "uniform mat4 projection;"
<< "uniform mat4 texture;"
- << "void main(void) {" << indent
- << "gl_Position = projection * position;";
+ << "void main(void) {" << indent << "gl_Position = projection * position;";
if (needs.isTexturing()) {
vs << "outTexCoords = (texture * texCoords).st;";
}
@@ -272,11 +268,10 @@
}
void ProgramCache::useProgram(const Description& description) {
-
// generate the key for the shader based on the description
Key needs(computeKey(description));
- // look-up the program in the cache
+ // look-up the program in the cache
Program* program = mCache.valueFor(needs);
if (program == NULL) {
// we didn't find our program, so generate one...
@@ -285,7 +280,7 @@
mCache.add(needs, program);
time += systemTime();
- //ALOGD(">>> generated new program: needs=%08X, time=%u ms (%d programs)",
+ // ALOGD(">>> generated new program: needs=%08X, time=%u ms (%d programs)",
// needs.mNeeds, uint32_t(ns2ms(time)), mCache.size());
}
@@ -296,5 +291,4 @@
}
}
-
} /* namespace android */
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h
index ff5cf0f..54d3722 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.h
@@ -19,8 +19,8 @@
#include <GLES2/gl2.h>
-#include <utils/Singleton.h>
#include <utils/KeyedVector.h>
+#include <utils/Singleton.h>
#include <utils/TypeHelpers.h>
#include "Description.h"
@@ -47,63 +47,50 @@
friend class ProgramCache;
typedef uint32_t key_t;
key_t mKey;
+
public:
enum {
- BLEND_PREMULT = 0x00000001,
- BLEND_NORMAL = 0x00000000,
- BLEND_MASK = 0x00000001,
+ BLEND_PREMULT = 0x00000001,
+ BLEND_NORMAL = 0x00000000,
+ BLEND_MASK = 0x00000001,
- OPACITY_OPAQUE = 0x00000002,
- OPACITY_TRANSLUCENT = 0x00000000,
- OPACITY_MASK = 0x00000002,
+ OPACITY_OPAQUE = 0x00000002,
+ OPACITY_TRANSLUCENT = 0x00000000,
+ OPACITY_MASK = 0x00000002,
- ALPHA_LT_ONE = 0x00000004,
- ALPHA_EQ_ONE = 0x00000000,
- ALPHA_MASK = 0x00000004,
+ ALPHA_LT_ONE = 0x00000004,
+ ALPHA_EQ_ONE = 0x00000000,
+ ALPHA_MASK = 0x00000004,
- TEXTURE_OFF = 0x00000000,
- TEXTURE_EXT = 0x00000008,
- TEXTURE_2D = 0x00000010,
- TEXTURE_MASK = 0x00000018,
+ TEXTURE_OFF = 0x00000000,
+ TEXTURE_EXT = 0x00000008,
+ TEXTURE_2D = 0x00000010,
+ TEXTURE_MASK = 0x00000018,
- COLOR_MATRIX_OFF = 0x00000000,
- COLOR_MATRIX_ON = 0x00000020,
- COLOR_MATRIX_MASK = 0x00000020,
+ COLOR_MATRIX_OFF = 0x00000000,
+ COLOR_MATRIX_ON = 0x00000020,
+ COLOR_MATRIX_MASK = 0x00000020,
- WIDE_GAMUT_OFF = 0x00000000,
- WIDE_GAMUT_ON = 0x00000040,
- WIDE_GAMUT_MASK = 0x00000040,
+ WIDE_GAMUT_OFF = 0x00000000,
+ WIDE_GAMUT_ON = 0x00000040,
+ WIDE_GAMUT_MASK = 0x00000040,
};
- inline Key() : mKey(0) { }
- inline Key(const Key& rhs) : mKey(rhs.mKey) { }
+ inline Key() : mKey(0) {}
+ inline Key(const Key& rhs) : mKey(rhs.mKey) {}
inline Key& set(key_t mask, key_t value) {
mKey = (mKey & ~mask) | value;
return *this;
}
- inline bool isTexturing() const {
- return (mKey & TEXTURE_MASK) != TEXTURE_OFF;
- }
- inline int getTextureTarget() const {
- return (mKey & TEXTURE_MASK);
- }
- inline bool isPremultiplied() const {
- return (mKey & BLEND_MASK) == BLEND_PREMULT;
- }
- inline bool isOpaque() const {
- return (mKey & OPACITY_MASK) == OPACITY_OPAQUE;
- }
- inline bool hasAlpha() const {
- return (mKey & ALPHA_MASK) == ALPHA_LT_ONE;
- }
- inline bool hasColorMatrix() const {
- return (mKey & COLOR_MATRIX_MASK) == COLOR_MATRIX_ON;
- }
- inline bool isWideGamut() const {
- return (mKey & WIDE_GAMUT_MASK) == WIDE_GAMUT_ON;
- }
+ inline bool isTexturing() const { return (mKey & TEXTURE_MASK) != TEXTURE_OFF; }
+ inline int getTextureTarget() const { return (mKey & TEXTURE_MASK); }
+ inline bool isPremultiplied() const { return (mKey & BLEND_MASK) == BLEND_PREMULT; }
+ inline bool isOpaque() const { return (mKey & OPACITY_MASK) == OPACITY_OPAQUE; }
+ inline bool hasAlpha() const { return (mKey & ALPHA_MASK) == ALPHA_LT_ONE; }
+ inline bool hasColorMatrix() const { return (mKey & COLOR_MATRIX_MASK) == COLOR_MATRIX_ON; }
+ inline bool isWideGamut() const { return (mKey & WIDE_GAMUT_MASK) == WIDE_GAMUT_ON; }
// this is the definition of a friend function -- not a method of class Needs
friend inline int strictly_order_type(const Key& lhs, const Key& rhs) {
@@ -135,7 +122,6 @@
DefaultKeyedVector<Key, Program*> mCache;
};
-
ANDROID_BASIC_TYPES_TRAITS(ProgramCache::Key)
} /* namespace android */
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 56e9ac0..883ae26 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -18,13 +18,13 @@
#include <ui/Rect.h>
#include <ui/Region.h>
-#include "RenderEngine.h"
#include "GLES20RenderEngine.h"
#include "GLExtensions.h"
#include "Mesh.h"
+#include "RenderEngine.h"
-#include <vector>
#include <SurfaceFlinger.h>
+#include <vector>
extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
@@ -33,21 +33,25 @@
// ---------------------------------------------------------------------------
static bool findExtension(const char* exts, const char* name) {
- if (!exts)
- return false;
+ if (!exts) return false;
size_t len = strlen(name);
const char* pos = exts;
while ((pos = strstr(pos, name)) != NULL) {
- if (pos[len] == '\0' || pos[len] == ' ')
- return true;
+ if (pos[len] == '\0' || pos[len] == ' ') return true;
pos += len;
}
return false;
}
-RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat, uint32_t featureFlags) {
+std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featureFlags) {
+ // initialize EGL for the default display
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!eglInitialize(display, NULL, NULL)) {
+ LOG_ALWAYS_FATAL("failed to initialize EGL");
+ }
+
// EGL_ANDROIDX_no_config_context is an experimental extension with no
// written specification. It will be replaced by something more formal.
// SurfaceFlinger is using it to allow a single EGLContext to render to
@@ -70,8 +74,7 @@
EGLint renderableType = 0;
if (config == EGL_NO_CONFIG) {
renderableType = EGL_OPENGL_ES2_BIT;
- } else if (!eglGetConfigAttrib(display, config,
- EGL_RENDERABLE_TYPE, &renderableType)) {
+ } else if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) {
LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");
}
EGLint contextClientVersion = 0;
@@ -96,12 +99,10 @@
contextAttributes.push_back(EGL_NONE);
contextAttributes.push_back(EGL_NONE);
- EGLContext ctxt = eglCreateContext(display, config, NULL,
- contextAttributes.data());
+ EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes.data());
// if can't create a GL context, we can only abort.
- LOG_ALWAYS_FATAL_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
-
+ LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
// now figure out what version of GL did we actually get
// NOTE: a dummy surface is not needed if KHR_create_context is supported
@@ -110,35 +111,32 @@
if (dummyConfig == EGL_NO_CONFIG) {
dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);
}
- EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE };
+ EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
EGLSurface dummy = eglCreatePbufferSurface(display, dummyConfig, attribs);
- LOG_ALWAYS_FATAL_IF(dummy==EGL_NO_SURFACE, "can't create dummy pbuffer");
+ LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");
EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");
GLExtensions& extensions(GLExtensions::getInstance());
- extensions.initWithGLStrings(
- glGetString(GL_VENDOR),
- glGetString(GL_RENDERER),
- glGetString(GL_VERSION),
- glGetString(GL_EXTENSIONS));
+ extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER),
+ glGetString(GL_VERSION), glGetString(GL_EXTENSIONS));
- GlesVersion version = parseGlesVersion( extensions.getVersion() );
+ GlesVersion version = parseGlesVersion(extensions.getVersion());
// initialize the renderer while GL is current
- RenderEngine* engine = NULL;
+ std::unique_ptr<RenderEngine> engine;
switch (version) {
- case GLES_VERSION_1_0:
- case GLES_VERSION_1_1:
- LOG_ALWAYS_FATAL("SurfaceFlinger requires OpenGL ES 2.0 minimum to run.");
- break;
- case GLES_VERSION_2_0:
- case GLES_VERSION_3_0:
- engine = new GLES20RenderEngine(featureFlags);
- break;
+ case GLES_VERSION_1_0:
+ case GLES_VERSION_1_1:
+ LOG_ALWAYS_FATAL("SurfaceFlinger requires OpenGL ES 2.0 minimum to run.");
+ break;
+ case GLES_VERSION_2_0:
+ case GLES_VERSION_3_0:
+ engine = std::make_unique<GLES20RenderEngine>(featureFlags);
+ break;
}
- engine->setEGLHandles(config, ctxt);
+ engine->setEGLHandles(display, config, ctxt);
ALOGI("OpenGL ES informations:");
ALOGI("vendor : %s", extensions.getVendor());
@@ -154,31 +152,50 @@
return engine;
}
-RenderEngine::RenderEngine() : mEGLConfig(NULL), mEGLContext(EGL_NO_CONTEXT) {
-}
+RenderEngine::RenderEngine()
+ : mEGLDisplay(EGL_NO_DISPLAY), mEGLConfig(NULL), mEGLContext(EGL_NO_CONTEXT) {}
RenderEngine::~RenderEngine() {
+ eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(mEGLDisplay);
}
-void RenderEngine::setEGLHandles(EGLConfig config, EGLContext ctxt) {
+void RenderEngine::setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt) {
+ mEGLDisplay = display;
mEGLConfig = config;
mEGLContext = ctxt;
}
-EGLContext RenderEngine::getEGLConfig() const {
+EGLDisplay RenderEngine::getEGLDisplay() const {
+ return mEGLDisplay;
+}
+
+EGLConfig RenderEngine::getEGLConfig() const {
return mEGLConfig;
}
-EGLContext RenderEngine::getEGLContext() const {
- return mEGLContext;
+bool RenderEngine::setCurrentSurface(const RE::Surface& surface) {
+ bool success = true;
+ EGLSurface eglSurface = surface.getEGLSurface();
+ if (eglSurface != eglGetCurrentSurface(EGL_DRAW)) {
+ success = eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext) == EGL_TRUE;
+ if (success && surface.getAsync()) {
+ eglSwapInterval(mEGLDisplay, 0);
+ }
+ }
+
+ return success;
+}
+
+void RenderEngine::resetCurrentSurface() {
+ eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
void RenderEngine::checkErrors() const {
do {
// there could be more than one error flag
GLenum error = glGetError();
- if (error == GL_NO_ERROR)
- break;
+ if (error == GL_NO_ERROR) break;
ALOGE("GL error 0x%04x", int(error));
} while (true);
}
@@ -201,32 +218,74 @@
return GLES_VERSION_1_0;
}
-void RenderEngine::fillRegionWithColor(const Region& region, uint32_t height,
- float red, float green, float blue, float alpha) {
+void RenderEngine::fillRegionWithColor(const Region& region, uint32_t height, float red,
+ float green, float blue, float alpha) {
size_t c;
Rect const* r = region.getArray(&c);
- Mesh mesh(Mesh::TRIANGLES, c*6, 2);
+ Mesh mesh(Mesh::TRIANGLES, c * 6, 2);
Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
- for (size_t i=0 ; i<c ; i++, r++) {
- position[i*6 + 0].x = r->left;
- position[i*6 + 0].y = height - r->top;
- position[i*6 + 1].x = r->left;
- position[i*6 + 1].y = height - r->bottom;
- position[i*6 + 2].x = r->right;
- position[i*6 + 2].y = height - r->bottom;
- position[i*6 + 3].x = r->left;
- position[i*6 + 3].y = height - r->top;
- position[i*6 + 4].x = r->right;
- position[i*6 + 4].y = height - r->bottom;
- position[i*6 + 5].x = r->right;
- position[i*6 + 5].y = height - r->top;
+ for (size_t i = 0; i < c; i++, r++) {
+ position[i * 6 + 0].x = r->left;
+ position[i * 6 + 0].y = height - r->top;
+ position[i * 6 + 1].x = r->left;
+ position[i * 6 + 1].y = height - r->bottom;
+ position[i * 6 + 2].x = r->right;
+ position[i * 6 + 2].y = height - r->bottom;
+ position[i * 6 + 3].x = r->left;
+ position[i * 6 + 3].y = height - r->top;
+ position[i * 6 + 4].x = r->right;
+ position[i * 6 + 4].y = height - r->bottom;
+ position[i * 6 + 5].x = r->right;
+ position[i * 6 + 5].y = height - r->top;
}
setupFillWithColor(red, green, blue, alpha);
drawMesh(mesh);
}
-void RenderEngine::flush() {
- glFlush();
+int RenderEngine::flush(bool wait) {
+ // Attempt to create a sync khr object that can produce a sync point. If that
+ // isn't available, create a non-dupable sync object in the fallback path and
+ // wait on it directly.
+ EGLSyncKHR sync;
+ if (!wait) {
+ EGLint syncFd = EGL_NO_NATIVE_FENCE_FD_ANDROID;
+
+ sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
+ if (sync != EGL_NO_SYNC_KHR) {
+ // native fence fd will not be populated until flush() is done.
+ glFlush();
+
+ // get the sync fd
+ syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
+ if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
+ ALOGW("failed to dup sync khr object");
+ }
+
+ eglDestroySyncKHR(mEGLDisplay, sync);
+ }
+
+ if (syncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID) {
+ return syncFd;
+ }
+ }
+
+ // fallback or explicit wait
+ sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
+ if (sync != EGL_NO_SYNC_KHR) {
+ EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
+ 2000000000 /*2 sec*/);
+ EGLint eglErr = eglGetError();
+ if (result == EGL_TIMEOUT_EXPIRED_KHR) {
+ ALOGW("fence wait timed out");
+ } else {
+ ALOGW_IF(eglErr != EGL_SUCCESS, "error waiting on EGL fence: %#x", eglErr);
+ }
+ eglDestroySyncKHR(mEGLDisplay, sync);
+ } else {
+ ALOGW("error creating EGL fence: %#x", eglGetError());
+ }
+
+ return -1;
}
void RenderEngine::clearWithColor(float red, float green, float blue, float alpha) {
@@ -234,8 +293,7 @@
glClear(GL_COLOR_BUFFER_BIT);
}
-void RenderEngine::setScissor(
- uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) {
+void RenderEngine::setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) {
glScissor(left, bottom, right, top);
glEnable(GL_SCISSOR_TEST);
}
@@ -257,38 +315,52 @@
}
void RenderEngine::dump(String8& result) {
+ result.appendFormat("EGL implementation : %s\n",
+ eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
+ result.appendFormat("%s\n", eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
+
const GLExtensions& extensions(GLExtensions::getInstance());
- result.appendFormat("GLES: %s, %s, %s\n",
- extensions.getVendor(),
- extensions.getRenderer(),
- extensions.getVersion());
+ result.appendFormat("GLES: %s, %s, %s\n", extensions.getVendor(), extensions.getRenderer(),
+ extensions.getVersion());
result.appendFormat("%s\n", extensions.getExtension());
}
// ---------------------------------------------------------------------------
-RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
- RenderEngine& engine, EGLImageKHR image) : mEngine(engine)
-{
- mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus);
+RenderEngine::BindNativeBufferAsFramebuffer::BindNativeBufferAsFramebuffer(
+ RenderEngine& engine, ANativeWindowBuffer* buffer)
+ : mEngine(engine) {
+ mImage = eglCreateImageKHR(mEngine.mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+ buffer, NULL);
+ if (mImage == EGL_NO_IMAGE_KHR) {
+ mStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ return;
+ }
- ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES,
- "glCheckFramebufferStatusOES error %d", mStatus);
+ mEngine.bindImageAsFramebuffer(mImage, &mTexName, &mFbName, &mStatus);
+
+ ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d",
+ mStatus);
}
-RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() {
+RenderEngine::BindNativeBufferAsFramebuffer::~BindNativeBufferAsFramebuffer() {
+ if (mImage == EGL_NO_IMAGE_KHR) {
+ return;
+ }
+
// back to main framebuffer
mEngine.unbindFramebuffer(mTexName, mFbName);
+ eglDestroyImageKHR(mEngine.mEGLDisplay, mImage);
}
-status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {
+status_t RenderEngine::BindNativeBufferAsFramebuffer::getStatus() const {
return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
}
// ---------------------------------------------------------------------------
-static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs,
- EGLint attribute, EGLint wanted, EGLConfig* outConfig) {
+static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, EGLint attribute,
+ EGLint wanted, EGLConfig* outConfig) {
EGLint numConfigs = -1, n = 0;
eglGetConfigs(dpy, NULL, 0, &numConfigs);
EGLConfig* const configs = new EGLConfig[numConfigs];
@@ -296,23 +368,23 @@
if (n) {
if (attribute != EGL_NONE) {
- for (int i=0 ; i<n ; i++) {
+ for (int i = 0; i < n; i++) {
EGLint value = 0;
eglGetConfigAttrib(dpy, configs[i], attribute, &value);
if (wanted == value) {
*outConfig = configs[i];
- delete [] configs;
+ delete[] configs;
return NO_ERROR;
}
}
} else {
// just pick the first one
*outConfig = configs[0];
- delete [] configs;
+ delete[] configs;
return NO_ERROR;
}
}
- delete [] configs;
+ delete[] configs;
return NAME_NOT_FOUND;
}
@@ -322,10 +394,10 @@
friend class Adder;
KeyedVector<Attribute, EGLint> mList;
struct Attribute {
- Attribute() : v(0) {};
- explicit Attribute(EGLint v) : v(v) { }
+ Attribute() : v(0){};
+ explicit Attribute(EGLint v) : v(v) {}
EGLint v;
- bool operator < (const Attribute& other) const {
+ bool operator<(const Attribute& other) const {
// this places EGL_NONE at the end
EGLint lhs(v);
EGLint rhs(other.v);
@@ -338,39 +410,32 @@
friend class EGLAttributeVector;
EGLAttributeVector& v;
EGLint attribute;
- Adder(EGLAttributeVector& v, EGLint attribute)
- : v(v), attribute(attribute) {
- }
+ Adder(EGLAttributeVector& v, EGLint attribute) : v(v), attribute(attribute) {}
+
public:
- void operator = (EGLint value) {
+ void operator=(EGLint value) {
if (attribute != EGL_NONE) {
v.mList.add(Attribute(attribute), value);
}
}
- operator EGLint () const { return v.mList[attribute]; }
+ operator EGLint() const { return v.mList[attribute]; }
};
+
public:
- EGLAttributeVector() {
- mList.add(Attribute(EGL_NONE), EGL_NONE);
- }
+ EGLAttributeVector() { mList.add(Attribute(EGL_NONE), EGL_NONE); }
void remove(EGLint attribute) {
if (attribute != EGL_NONE) {
mList.removeItem(Attribute(attribute));
}
}
- Adder operator [] (EGLint attribute) {
- return Adder(*this, attribute);
- }
- EGLint operator [] (EGLint attribute) const {
- return mList[attribute];
- }
+ Adder operator[](EGLint attribute) { return Adder(*this, attribute); }
+ EGLint operator[](EGLint attribute) const { return mList[attribute]; }
// cast-operator to (EGLint const*)
- operator EGLint const* () const { return &mList.keyAt(0).v; }
+ operator EGLint const*() const { return &mList.keyAt(0).v; }
};
-
-static status_t selectEGLConfig(EGLDisplay display, EGLint format,
- EGLint renderableType, EGLConfig* config) {
+static status_t selectEGLConfig(EGLDisplay display, EGLint format, EGLint renderableType,
+ EGLConfig* config) {
// select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
// it is to be used with WIFI displays
status_t err;
@@ -379,24 +444,23 @@
EGLAttributeVector attribs;
if (renderableType) {
- attribs[EGL_RENDERABLE_TYPE] = renderableType;
- attribs[EGL_RECORDABLE_ANDROID] = EGL_TRUE;
- attribs[EGL_SURFACE_TYPE] = EGL_WINDOW_BIT|EGL_PBUFFER_BIT;
+ attribs[EGL_RENDERABLE_TYPE] = renderableType;
+ attribs[EGL_RECORDABLE_ANDROID] = EGL_TRUE;
+ attribs[EGL_SURFACE_TYPE] = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE;
- attribs[EGL_RED_SIZE] = 8;
- attribs[EGL_GREEN_SIZE] = 8;
- attribs[EGL_BLUE_SIZE] = 8;
- attribs[EGL_ALPHA_SIZE] = 8;
- wantedAttribute = EGL_NONE;
- wantedAttributeValue = EGL_NONE;
+ attribs[EGL_RED_SIZE] = 8;
+ attribs[EGL_GREEN_SIZE] = 8;
+ attribs[EGL_BLUE_SIZE] = 8;
+ attribs[EGL_ALPHA_SIZE] = 8;
+ wantedAttribute = EGL_NONE;
+ wantedAttributeValue = EGL_NONE;
} else {
// if no renderable type specified, fallback to a simplified query
- wantedAttribute = EGL_NATIVE_VISUAL_ID;
- wantedAttributeValue = format;
+ wantedAttribute = EGL_NATIVE_VISUAL_ID;
+ wantedAttributeValue = format;
}
- err = selectConfigForAttribute(display, attribs,
- wantedAttribute, wantedAttributeValue, config);
+ err = selectConfigForAttribute(display, attribs, wantedAttribute, wantedAttributeValue, config);
if (err == NO_ERROR) {
EGLint caveat;
if (eglGetConfigAttrib(display, *config, EGL_CONFIG_CAVEAT, &caveat))
@@ -406,8 +470,7 @@
return err;
}
-EGLConfig RenderEngine::chooseEglConfig(EGLDisplay display, int format,
- bool logConfig) {
+EGLConfig RenderEngine::chooseEglConfig(EGLDisplay display, int format, bool logConfig) {
status_t err;
EGLConfig config;
@@ -430,23 +493,22 @@
if (logConfig) {
// print some debugging info
- EGLint r,g,b,a;
- eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r);
+ EGLint r, g, b, a;
+ eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r);
eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
- eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b);
+ eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b);
eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
ALOGI("EGL information:");
ALOGI("vendor : %s", eglQueryString(display, EGL_VENDOR));
ALOGI("version : %s", eglQueryString(display, EGL_VERSION));
ALOGI("extensions: %s", eglQueryString(display, EGL_EXTENSIONS));
- ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
+ ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS) ?: "Not Supported");
ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
}
return config;
}
-
void RenderEngine::primeCache() const {
// Getting the ProgramCache instance causes it to prime its shader cache,
// which is performed in its constructor
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 7e05cec..3847347 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -14,21 +14,24 @@
* limitations under the License.
*/
-
#ifndef SF_RENDERENGINE_H_
#define SF_RENDERENGINE_H_
+#include <memory>
+
#include <stdint.h>
#include <sys/types.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <math/mat4.h>
#include <Transform.h>
#include <gui/SurfaceControl.h>
+#include <math/mat4.h>
#define EGL_NO_CONFIG ((EGLConfig)0)
+struct ANativeWindowBuffer;
+
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
@@ -39,31 +42,38 @@
class Mesh;
class Texture;
+namespace RE {
+class Surface;
+}
+
class RenderEngine {
enum GlesVersion {
- GLES_VERSION_1_0 = 0x10000,
- GLES_VERSION_1_1 = 0x10001,
- GLES_VERSION_2_0 = 0x20000,
- GLES_VERSION_3_0 = 0x30000,
+ GLES_VERSION_1_0 = 0x10000,
+ GLES_VERSION_1_1 = 0x10001,
+ GLES_VERSION_2_0 = 0x20000,
+ GLES_VERSION_3_0 = 0x30000,
};
static GlesVersion parseGlesVersion(const char* str);
+ EGLDisplay mEGLDisplay;
EGLConfig mEGLConfig;
EGLContext mEGLContext;
- void setEGLHandles(EGLConfig config, EGLContext ctxt);
+ void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt);
- virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0;
+ virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName,
+ uint32_t* status) = 0;
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
protected:
RenderEngine();
- virtual ~RenderEngine() = 0;
public:
+ virtual ~RenderEngine() = 0;
+
enum FeatureFlag {
WIDE_COLOR_SUPPORT = 1 << 0 // Platform has a wide color display
};
- static RenderEngine* create(EGLDisplay display, int hwcFormat, uint32_t featureFlags);
+ static std::unique_ptr<RenderEngine> create(int hwcFormat, uint32_t featureFlags);
static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
@@ -73,10 +83,11 @@
virtual void dump(String8& result);
// helpers
- void flush();
+ // flush returns -1 or a valid native fence fd owned by the caller
+ int flush(bool wait);
void clearWithColor(float red, float green, float blue, float alpha);
- void fillRegionWithColor(const Region& region, uint32_t height,
- float red, float green, float blue, float alpha);
+ void fillRegionWithColor(const Region& region, uint32_t height, float red, float green,
+ float blue, float alpha);
// common to all GL versions
void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top);
@@ -85,22 +96,27 @@
void deleteTextures(size_t count, uint32_t const* names);
void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels);
- class BindImageAsFramebuffer {
+ class BindNativeBufferAsFramebuffer {
RenderEngine& mEngine;
+ EGLImageKHR mImage;
uint32_t mTexName, mFbName;
uint32_t mStatus;
+
public:
- BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image);
- ~BindImageAsFramebuffer();
+ BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer);
+ ~BindNativeBufferAsFramebuffer();
int getStatus() const;
};
+ bool setCurrentSurface(const RE::Surface& surface);
+ void resetCurrentSurface();
+
// set-up
virtual void checkErrors() const;
- virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0;
- virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
- bool disableTexture, const half4& color) = 0;
+ virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop, size_t hwh,
+ bool yswap, Transform::orientation_flags rotation) = 0;
+ virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
+ const half4& color) = 0;
virtual void setColorMode(android_color_mode mode) = 0;
virtual void setSourceDataSpace(android_dataspace source) = 0;
virtual void setWideColor(bool hasWideColor) = 0;
@@ -109,9 +125,7 @@
virtual void setupLayerBlackedOut() = 0;
virtual void setupFillWithColor(float r, float g, float b, float a) = 0;
- virtual mat4 setupColorTransform(const mat4& /* colorTransform */) {
- return mat4();
- }
+ virtual mat4 setupColorTransform(const mat4& /* colorTransform */) { return mat4(); }
virtual void disableTexturing() = 0;
virtual void disableBlending() = 0;
@@ -123,8 +137,9 @@
virtual size_t getMaxTextureSize() const = 0;
virtual size_t getMaxViewportDims() const = 0;
+ // internal to RenderEngine
+ EGLDisplay getEGLDisplay() const;
EGLConfig getEGLConfig() const;
- EGLContext getEGLContext() const;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/Surface.cpp b/services/surfaceflinger/RenderEngine/Surface.cpp
new file mode 100644
index 0000000..a23d9fb
--- /dev/null
+++ b/services/surfaceflinger/RenderEngine/Surface.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#include "Surface.h"
+
+#include "RenderEngine.h"
+
+#include <log/log.h>
+
+namespace android {
+namespace RE {
+
+Surface::Surface(const RenderEngine& 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 = RenderEngine::chooseEglConfig(mEGLDisplay, PIXEL_FORMAT_RGBA_8888, false);
+ }
+}
+
+Surface::~Surface() {
+ setNativeWindow(nullptr);
+}
+
+void Surface::setNativeWindow(ANativeWindow* window) {
+ if (mEGLSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(mEGLDisplay, mEGLSurface);
+ mEGLSurface = EGL_NO_SURFACE;
+ }
+
+ mWindow = window;
+ if (mWindow) {
+ mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mWindow, nullptr);
+ }
+}
+
+void Surface::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 Surface::queryConfig(EGLint attrib) const {
+ EGLint value;
+ if (!eglGetConfigAttrib(mEGLConfig, mEGLConfig, attrib, &value)) {
+ value = 0;
+ }
+
+ return value;
+}
+
+EGLint Surface::querySurface(EGLint attrib) const {
+ EGLint value;
+ if (!eglQuerySurface(mEGLDisplay, mEGLSurface, attrib, &value)) {
+ value = 0;
+ }
+
+ return value;
+}
+
+int32_t Surface::queryRedSize() const {
+ return queryConfig(EGL_RED_SIZE);
+}
+
+int32_t Surface::queryGreenSize() const {
+ return queryConfig(EGL_GREEN_SIZE);
+}
+
+int32_t Surface::queryBlueSize() const {
+ return queryConfig(EGL_BLUE_SIZE);
+}
+
+int32_t Surface::queryAlphaSize() const {
+ return queryConfig(EGL_ALPHA_SIZE);
+}
+
+int32_t Surface::queryWidth() const {
+ return querySurface(EGL_WIDTH);
+}
+
+int32_t Surface::queryHeight() const {
+ return querySurface(EGL_HEIGHT);
+}
+
+} // namespace RE
+} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/Surface.h b/services/surfaceflinger/RenderEngine/Surface.h
new file mode 100644
index 0000000..8b10be9
--- /dev/null
+++ b/services/surfaceflinger/RenderEngine/Surface.h
@@ -0,0 +1,73 @@
+/*
+ * 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>
+
+#include <EGL/egl.h>
+
+struct ANativeWindow;
+
+namespace android {
+
+class RenderEngine;
+
+namespace RE {
+
+class Surface {
+public:
+ Surface(const RenderEngine& engine);
+ ~Surface();
+
+ Surface(const Surface&) = delete;
+ Surface& operator=(const Surface&) = delete;
+
+ void setCritical(bool enable) { mCritical = enable; }
+ void setAsync(bool enable) { mAsync = enable; }
+
+ void setNativeWindow(ANativeWindow* window);
+ void swapBuffers() const;
+
+ int32_t queryRedSize() const;
+ int32_t queryGreenSize() const;
+ int32_t queryBlueSize() const;
+ int32_t queryAlphaSize() const;
+
+ int32_t queryWidth() const;
+ int32_t queryHeight() const;
+
+private:
+ EGLint queryConfig(EGLint attrib) const;
+ EGLint querySurface(EGLint attrib) const;
+
+ // methods internal to RenderEngine
+ friend class android::RenderEngine;
+ bool getAsync() const { return mAsync; }
+ EGLSurface getEGLSurface() const { return mEGLSurface; }
+
+ EGLDisplay mEGLDisplay;
+ EGLConfig mEGLConfig;
+
+ bool mCritical = false;
+ bool mAsync = false;
+
+ ANativeWindow* mWindow = nullptr;
+ EGLSurface mEGLSurface = EGL_NO_SURFACE;
+};
+
+} // namespace RE
+} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/Texture.cpp b/services/surfaceflinger/RenderEngine/Texture.cpp
index 8875b6d..351430f 100644
--- a/services/surfaceflinger/RenderEngine/Texture.cpp
+++ b/services/surfaceflinger/RenderEngine/Texture.cpp
@@ -20,24 +20,22 @@
namespace android {
-Texture::Texture() :
- mTextureName(0), mTextureTarget(TEXTURE_2D),
- mWidth(0), mHeight(0), mFiltering(false) {
-}
+Texture::Texture()
+ : mTextureName(0), mTextureTarget(TEXTURE_2D), mWidth(0), mHeight(0), mFiltering(false) {}
-Texture::Texture(Target textureTarget, uint32_t textureName) :
- mTextureName(textureName), mTextureTarget(textureTarget),
- mWidth(0), mHeight(0), mFiltering(false) {
-}
+Texture::Texture(Target textureTarget, uint32_t textureName)
+ : mTextureName(textureName),
+ mTextureTarget(textureTarget),
+ mWidth(0),
+ mHeight(0),
+ mFiltering(false) {}
void Texture::init(Target textureTarget, uint32_t textureName) {
mTextureName = textureName;
mTextureTarget = textureTarget;
}
-Texture::~Texture() {
-}
-
+Texture::~Texture() {}
void Texture::setMatrix(float const* matrix) {
mTextureMatrix = mat4(matrix);
diff --git a/services/surfaceflinger/RenderEngine/Texture.h b/services/surfaceflinger/RenderEngine/Texture.h
index a07e0c3..56b6b31 100644
--- a/services/surfaceflinger/RenderEngine/Texture.h
+++ b/services/surfaceflinger/RenderEngine/Texture.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include <stdint.h>
#include <math/mat4.h>
+#include <stdint.h>
#ifndef SF_RENDER_ENGINE_TEXTURE_H
#define SF_RENDER_ENGINE_TEXTURE_H
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f29d980..555f4a8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -28,8 +28,6 @@
#include <stdatomic.h>
#include <optional>
-#include <EGL/egl.h>
-
#include <cutils/properties.h>
#include <log/log.h>
@@ -101,8 +99,6 @@
*/
#define DEBUG_SCREENSHOTS false
-extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
-
namespace android {
using namespace android::hardware::configstore;
@@ -285,9 +281,6 @@
SurfaceFlinger::~SurfaceFlinger()
{
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglTerminate(display);
}
void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
@@ -594,10 +587,6 @@
Mutex::Autolock _l(mStateLock);
- // initialize EGL for the default display
- mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(mEGLDisplay, NULL, NULL);
-
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
@@ -618,15 +607,9 @@
}
// Get a RenderEngine for the given display / config (can't fail)
- mRenderEngine = RenderEngine::create(mEGLDisplay,
- HAL_PIXEL_FORMAT_RGBA_8888,
+ mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);
-
- // retrieve the EGL context that was selected/created
- mEGLContext = mRenderEngine->getEGLContext();
-
- LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
- "couldn't create EGLContext");
+ LOG_ALWAYS_FATAL_IF(mRenderEngine == nullptr, "couldn't create RenderEngine");
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
"Starting with vr flinger active is not currently supported.");
@@ -1308,8 +1291,7 @@
}
bool useWideColorMode = hasWideColorModes && hasWideColorDisplay && !mForceNativeColorMode;
sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
- token, fbs, producer, mRenderEngine->getEGLConfig(),
- useWideColorMode);
+ token, fbs, producer, useWideColorMode);
mDisplays.add(token, hw);
android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
if (useWideColorMode) {
@@ -1324,7 +1306,7 @@
// make the GLContext current so that we can create textures when creating
// Layers (which may happens before we render something)
- hw->makeCurrent(mEGLDisplay, mEGLContext);
+ hw->makeCurrent();
}
void SurfaceFlinger::onHotplugReceived(int32_t sequenceId,
@@ -1395,7 +1377,7 @@
// mCurrentState and mDrawingState and re-apply all changes when we make the
// transition.
mDrawingState.displays.clear();
- eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ getRenderEngine().resetCurrentSurface();
mDisplays.clear();
}
@@ -1552,7 +1534,7 @@
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
if (!dirtyRegion.isEmpty()) {
// redraw the whole screen
- doComposeSurfaces(hw, Region(hw->bounds()));
+ doComposeSurfaces(hw);
// and draw the dirty region
const int32_t height = hw->getHeight();
@@ -2027,8 +2009,7 @@
doDisplayComposition(hw, dirtyRegion);
hw->dirtyRegion.clear();
- hw->flip(hw->swapRegion);
- hw->swapRegion.clear();
+ hw->flip();
}
}
postFramebuffer();
@@ -2052,7 +2033,7 @@
mHwc->presentAndGetReleaseFences(hwcId);
}
displayDevice->onSwapBuffersCompleted();
- displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
+ displayDevice->makeCurrent();
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
// The layer buffer from the previous frame (if any) is released
// by HWC only when the release fence from this frame (if any) is
@@ -2178,7 +2159,7 @@
// be sure that nothing associated with this display
// is current.
const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
- defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
+ defaultDisplay->makeCurrent();
sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));
if (hw != NULL)
hw->disconnect(getHwComposer());
@@ -2296,9 +2277,7 @@
if (dispSurface != NULL) {
sp<DisplayDevice> hw =
new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
- dispSurface, producer,
- mRenderEngine->getEGLConfig(),
- hasWideColorDisplay);
+ dispSurface, producer, hasWideColorDisplay);
hw->setLayerStack(state.layerStack);
hw->setProjection(state.orientation,
state.viewport, state.frame);
@@ -2663,46 +2642,17 @@
}
ALOGV("doDisplayComposition");
-
- Region dirtyRegion(inDirtyRegion);
-
- // compute the invalid region
- displayDevice->swapRegion.orSelf(dirtyRegion);
-
- uint32_t flags = displayDevice->getFlags();
- if (flags & DisplayDevice::SWAP_RECTANGLE) {
- // we can redraw only what's dirty, but since SWAP_RECTANGLE only
- // takes a rectangle, we must make sure to update that whole
- // rectangle in that case
- dirtyRegion.set(displayDevice->swapRegion.bounds());
- } else {
- if (flags & DisplayDevice::PARTIAL_UPDATES) {
- // We need to redraw the rectangle that will be updated
- // (pushed to the framebuffer).
- // This is needed because PARTIAL_UPDATES only takes one
- // rectangle instead of a region (see DisplayDevice::flip())
- dirtyRegion.set(displayDevice->swapRegion.bounds());
- } else {
- // we need to redraw everything (the whole screen)
- dirtyRegion.set(displayDevice->bounds());
- displayDevice->swapRegion = dirtyRegion;
- }
- }
-
- if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;
-
- // update the swap region and clear the dirty region
- displayDevice->swapRegion.orSelf(dirtyRegion);
+ if (!doComposeSurfaces(displayDevice)) return;
// swap buffers (presentation)
displayDevice->swapBuffers(getHwComposer());
}
-bool SurfaceFlinger::doComposeSurfaces(
- const sp<const DisplayDevice>& displayDevice, const Region& dirty)
+bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDevice)
{
ALOGV("doComposeSurfaces");
+ const Region bounds(displayDevice->bounds());
const DisplayRenderArea renderArea(displayDevice);
const auto hwcId = displayDevice->getHwcDisplayId();
@@ -2722,13 +2672,13 @@
displayDevice->getWideColorSupport() && !mForceNativeColorMode);
mRenderEngine->setColorMode(mForceNativeColorMode ?
HAL_COLOR_MODE_NATIVE : displayDevice->getActiveColorMode());
- if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
+ if (!displayDevice->makeCurrent()) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
displayDevice->getDisplayName().string());
- eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ getRenderEngine().resetCurrentSurface();
// |mStateLock| not needed as we are on the main thread
- if(!getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext)) {
+ if(!getDefaultDisplayDeviceLocked()->makeCurrent()) {
ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
}
return false;
@@ -2744,10 +2694,7 @@
// We'll revisit later if needed.
mRenderEngine->clearWithColor(0, 0, 0, 0);
} else {
- // we start with the whole screen area
- const Region bounds(displayDevice->getBounds());
-
- // we remove the scissor part
+ // we start with the whole screen area and remove the scissor part
// we're left with the letterbox region
// (common case is that letterbox ends-up being empty)
const Region letterbox(bounds.subtract(displayDevice->getScissor()));
@@ -2755,9 +2702,6 @@
// compute the area to clear
Region region(displayDevice->undefinedRegion.merge(letterbox));
- // but limit it to the dirty region
- region.andSelf(dirty);
-
// screen is already cleared here
if (!region.isEmpty()) {
// can happen with SurfaceView
@@ -2794,7 +2738,7 @@
// we're using h/w composer
bool firstLayer = true;
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
- const Region clip(dirty.intersect(
+ const Region clip(bounds.intersect(
displayTransform.transform(layer->visibleRegion)));
ALOGV("Layer: %s", layer->getName().string());
ALOGV(" Composition type: %s",
@@ -2830,7 +2774,7 @@
} else {
// we're not using h/w composer
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
- const Region clip(dirty.intersect(
+ const Region clip(bounds.intersect(
displayTransform.transform(layer->visibleRegion)));
if (!clip.isEmpty()) {
layer->draw(renderArea, clip);
@@ -3937,13 +3881,6 @@
HWComposer& hwc(getHwComposer());
sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
- colorizer.bold(result);
- result.appendFormat("EGL implementation : %s\n",
- eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
- colorizer.reset(result);
- result.appendFormat("%s\n",
- eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
-
mRenderEngine->dump(result);
hw->undefinedRegion.dump(result, "undefinedRegion");
@@ -4626,26 +4563,6 @@
});
}
-// A simple RAII class that holds an EGLImage and destroys it either:
-// a) When the destroy() method is called
-// b) When the object goes out of scope
-class ImageHolder {
-public:
- ImageHolder(EGLDisplay display, EGLImageKHR image) : mDisplay(display), mImage(image) {}
- ~ImageHolder() { destroy(); }
-
- void destroy() {
- if (mImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mDisplay, mImage);
- mImage = EGL_NO_IMAGE_KHR;
- }
- }
-
-private:
- const EGLDisplay mDisplay;
- EGLImageKHR mImage;
-};
-
status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer,
@@ -4664,23 +4581,11 @@
return PERMISSION_DENIED;
}
- int syncFd = -1;
- // create an EGLImage from the buffer so we can later
- // turn it into a texture
- EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
- EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
- if (image == EGL_NO_IMAGE_KHR) {
- return BAD_VALUE;
- }
-
- // This will automatically destroy the image if we return before calling its destroy method
- ImageHolder imageHolder(mEGLDisplay, image);
-
// this binds the given EGLImage as a framebuffer for the
// duration of this scope.
- RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
- if (imageBond.getStatus() != NO_ERROR) {
- ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
+ RenderEngine::BindNativeBufferAsFramebuffer bufferBond(getRenderEngine(), buffer);
+ if (bufferBond.getStatus() != NO_ERROR) {
+ ALOGE("got ANWB binding error while taking screenshot");
return INVALID_OPERATION;
}
@@ -4690,43 +4595,7 @@
// dependent on the context's EGLConfig.
renderScreenImplLocked(renderArea, traverseLayers, true, useIdentityTransform);
- // Attempt to create a sync khr object that can produce a sync point. If that
- // isn't available, create a non-dupable sync object in the fallback path and
- // wait on it directly.
- EGLSyncKHR sync = EGL_NO_SYNC_KHR;
- if (!DEBUG_SCREENSHOTS) {
- sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
- // native fence fd will not be populated until flush() is done.
- getRenderEngine().flush();
- }
-
- if (sync != EGL_NO_SYNC_KHR) {
- // get the sync fd
- syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
- if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
- ALOGW("captureScreen: failed to dup sync khr object");
- syncFd = -1;
- }
- eglDestroySyncKHR(mEGLDisplay, sync);
- } else {
- // fallback path
- sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
- if (sync != EGL_NO_SYNC_KHR) {
- EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
- EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
- EGLint eglErr = eglGetError();
- if (result == EGL_TIMEOUT_EXPIRED_KHR) {
- ALOGW("captureScreen: fence wait timed out");
- } else {
- ALOGW_IF(eglErr != EGL_SUCCESS,
- "captureScreen: error waiting on EGL fence: %#x", eglErr);
- }
- eglDestroySyncKHR(mEGLDisplay, sync);
- } else {
- ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
- }
- }
- *outSyncFd = syncFd;
+ *outSyncFd = getRenderEngine().flush(DEBUG_SCREENSHOTS);
if (DEBUG_SCREENSHOTS) {
const auto reqWidth = renderArea.getReqWidth();
@@ -4738,8 +4607,6 @@
delete [] pixels;
}
- // destroy our image
- imageHolder.destroy();
return NO_ERROR;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f61dc75..d991f68 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -21,8 +21,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <EGL/egl.h>
-
/*
* NOTE: Make sure this file doesn't include anything from <gl/ > or <gl2/ >
*/
@@ -549,7 +547,7 @@
// compose surfaces for display hw. this fails if using GL and the surface
// has been destroyed and is no longer valid.
- bool doComposeSurfaces(const sp<const DisplayDevice>& displayDevice, const Region& dirty);
+ bool doComposeSurfaces(const sp<const DisplayDevice>& displayDevice);
void postFramebuffer();
void drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const;
@@ -663,7 +661,7 @@
const std::string mHwcServiceName; // "default" for real use, something else for testing.
// constant members (no synchronization needed for access)
- RenderEngine* mRenderEngine;
+ std::unique_ptr<RenderEngine> mRenderEngine;
nsecs_t mBootTime;
bool mGpuToCpuSupported;
sp<EventThread> mEventThread;
@@ -671,8 +669,6 @@
sp<EventThread> mInjectorEventThread;
sp<InjectVSyncSource> mVSyncInjector;
sp<EventControlThread> mEventControlThread;
- EGLContext mEGLContext;
- EGLDisplay mEGLDisplay;
sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];
// Can only accessed from the main thread, these members