SF: Separate RenderEngine into interface and impl
This allows the RenderEngine to be substituted by a GMock for tests.
RE::RenderEngine is now a pure virtual interface class.
RE::impl::RenderEngine is the normal/base implementation.
Similarly, RE::Image and RE::Surface are pure virtual interfaces.
RE::impl::Image and RE::impl::Surface are the normal implementations.
Test: Builds
Bug: None
Change-Id: Ib5e658df4bb4efc1a9c0ae95feaf0c1e052cdc94
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 4d4c9fc..3dbc136 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -200,7 +200,7 @@
bool blackOutLayer = isProtected() || (isSecure() && !renderArea.isSecure());
- RenderEngine& engine(mFlinger->getRenderEngine());
+ auto& engine(mFlinger->getRenderEngine());
if (!blackOutLayer) {
// TODO: we could be more subtle with isFixedSize()
@@ -817,7 +817,7 @@
texCoords[2] = vec2(right, 1.0f - bottom);
texCoords[3] = vec2(right, 1.0f - top);
- RenderEngine& engine(mFlinger->getRenderEngine());
+ auto& engine(mFlinger->getRenderEngine());
engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */,
getColor());
engine.setSourceDataSpace(mCurrentState.dataSpace);
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 4d9b43f..46ec0e3 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -23,6 +23,7 @@
#include "DispSync.h"
#include "Layer.h"
+#include "RenderEngine/Image.h"
#include "RenderEngine/RenderEngine.h"
#include <inttypes.h>
@@ -56,8 +57,8 @@
static const mat4 mtxIdentity;
-BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RenderEngine& engine,
- uint32_t tex, Layer* layer)
+BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq,
+ RE::RenderEngine& engine, uint32_t tex, Layer* layer)
: ConsumerBase(bq, false),
mCurrentCrop(Rect::EMPTY_RECT),
mCurrentTransform(0),
@@ -359,7 +360,7 @@
if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) {
BLC_LOGE("bindTextureImage: no currently-bound texture");
- mRE.bindExternalTextureImage(mTexName, RE::Image(mRE));
+ mRE.bindExternalTextureImage(mTexName, *mRE.createImage());
return NO_INIT;
}
@@ -367,7 +368,7 @@
status_t err = mCurrentTextureImage->createIfNeeded(imageCrop);
if (err != NO_ERROR) {
BLC_LOGW("bindTextureImage: can't create image on slot=%d", mCurrentTexture);
- mRE.bindExternalTextureImage(mTexName, RE::Image(mRE));
+ mRE.bindExternalTextureImage(mTexName, *mRE.createImage());
return UNKNOWN_ERROR;
}
@@ -604,13 +605,15 @@
ConsumerBase::dumpLocked(result, prefix);
}
-BufferLayerConsumer::Image::Image(sp<GraphicBuffer> graphicBuffer, const RenderEngine& engine)
+BufferLayerConsumer::Image::Image(sp<GraphicBuffer> graphicBuffer, RE::RenderEngine& engine)
: mGraphicBuffer(graphicBuffer),
- mImage{engine},
+ mImage{engine.createImage()},
mCreated(false),
mCropWidth(0),
mCropHeight(0) {}
+BufferLayerConsumer::Image::~Image() = default;
+
status_t BufferLayerConsumer::Image::createIfNeeded(const Rect& imageCrop) {
const int32_t cropWidth = imageCrop.width();
const int32_t cropHeight = imageCrop.height();
@@ -618,9 +621,9 @@
return OK;
}
- mCreated = mImage.setNativeWindowBuffer(mGraphicBuffer->getNativeBuffer(),
- mGraphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED,
- cropWidth, cropHeight);
+ mCreated = mImage->setNativeWindowBuffer(mGraphicBuffer->getNativeBuffer(),
+ mGraphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED,
+ cropWidth, cropHeight);
if (mCreated) {
mCropWidth = cropWidth;
mCropHeight = cropHeight;
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index a0272b3..11048d8 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -17,8 +17,6 @@
#ifndef ANDROID_BUFFERLAYERCONSUMER_H
#define ANDROID_BUFFERLAYERCONSUMER_H
-#include "RenderEngine/Image.h"
-
#include <gui/BufferQueueDefs.h>
#include <gui/ConsumerBase.h>
#include <gui/HdrMetadata.h>
@@ -36,9 +34,13 @@
class DispSync;
class Layer;
-class RenderEngine;
class String8;
+namespace RE {
+class RenderEngine;
+class Image;
+} // namespace RE
+
/*
* BufferLayerConsumer consumes buffers of graphics data from a BufferQueue,
* and makes them available to RenderEngine as a texture.
@@ -70,8 +72,8 @@
// BufferLayerConsumer constructs a new BufferLayerConsumer object. The
// tex parameter indicates the name of the RenderEngine texture to which
// images are to be streamed.
- BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RenderEngine& engine, uint32_t tex,
- Layer* layer);
+ BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RE::RenderEngine& engine,
+ uint32_t tex, Layer* layer);
// Sets the contents changed listener. This should be used instead of
// ConsumerBase::setFrameAvailableListener().
@@ -220,7 +222,7 @@
// also only creating new RE::Images from buffers when required.
class Image : public LightRefBase<Image> {
public:
- Image(sp<GraphicBuffer> graphicBuffer, const RenderEngine& engine);
+ Image(sp<GraphicBuffer> graphicBuffer, RE::RenderEngine& engine);
Image(const Image& rhs) = delete;
Image& operator=(const Image& rhs) = delete;
@@ -234,18 +236,18 @@
return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle;
}
- const RE::Image& image() const { return mImage; }
+ const RE::Image& image() const { return *mImage; }
private:
// Only allow instantiation using ref counting.
friend class LightRefBase<Image>;
- virtual ~Image() = default;
+ virtual ~Image();
// mGraphicBuffer is the buffer that was used to create this image.
sp<GraphicBuffer> mGraphicBuffer;
// mImage is the image created from mGraphicBuffer.
- RE::Image mImage;
+ std::unique_ptr<RE::Image> mImage;
bool mCreated;
int32_t mCropWidth;
int32_t mCropHeight;
@@ -349,7 +351,7 @@
// setFilteringEnabled().
bool mFilteringEnabled;
- RenderEngine& mRE;
+ RE::RenderEngine& mRE;
// mTexName is the name of the RenderEngine texture to which streamed
// images will be bound when bindTexImage is called. It is set at
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 10e7790..80a90a7 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -48,7 +48,7 @@
if (s.color.a > 0) {
Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
computeGeometry(renderArea, mesh, useIdentityTransform);
- RenderEngine& engine(mFlinger->getRenderEngine());
+ auto& engine(mFlinger->getRenderEngine());
engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */,
true /* disableTexture */, s.color);
engine.drawMesh(mesh);
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index cf70529..d40666e 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -84,7 +84,7 @@
mHwcDisplayId(hwcId),
mDisplayToken(displayToken),
mDisplaySurface(displaySurface),
- mSurface{flinger->getRenderEngine()},
+ mSurface{flinger->getRenderEngine().createSurface()},
mDisplayWidth(),
mDisplayHeight(),
mPageFlipCount(),
@@ -106,11 +106,11 @@
/*
* Create our display's surface
*/
- mSurface.setCritical(mType == DisplayDevice::DISPLAY_PRIMARY);
- mSurface.setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL);
- mSurface.setNativeWindow(window);
- mDisplayWidth = mSurface.queryWidth();
- mDisplayHeight = mSurface.queryHeight();
+ 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
@@ -207,7 +207,7 @@
void DisplayDevice::swapBuffers(HWComposer& hwc) const {
if (hwc.hasClientComposition(mHwcDisplayId) || hwc.hasFlipClientTargetRequest(mHwcDisplayId)) {
- mSurface.swapBuffers();
+ mSurface->swapBuffers();
}
status_t result = mDisplaySurface->advanceFrame();
@@ -222,7 +222,7 @@
}
bool DisplayDevice::makeCurrent() const {
- bool success = mFlinger->getRenderEngine().setCurrentSurface(mSurface);
+ bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface);
setViewportAndProjection();
return success;
}
@@ -360,14 +360,14 @@
void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
dirtyRegion.set(getBounds());
- mSurface.setNativeWindow(nullptr);
+ mSurface->setNativeWindow(nullptr);
mDisplaySurface->resizeBuffers(newWidth, newHeight);
ANativeWindow* const window = mNativeWindow.get();
- mSurface.setNativeWindow(window);
- mDisplayWidth = mSurface.queryWidth();
- mDisplayHeight = mSurface.queryHeight();
+ mSurface->setNativeWindow(window);
+ mDisplayWidth = mSurface->queryWidth();
+ mDisplayHeight = mSurface->queryHeight();
LOG_FATAL_IF(mDisplayWidth != newWidth,
"Unable to set new width to %d", newWidth);
@@ -474,9 +474,9 @@
"(%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,
- mSurface.queryRedSize(), mSurface.queryGreenSize(), mSurface.queryBlueSize(),
- mSurface.queryAlphaSize(), mOrientation, tr.getType(),
- getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
+ mSurface->queryRedSize(), mSurface->queryGreenSize(),
+ mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation,
+ tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
mVisibleLayersSortedByZ.size());
result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index a470670..d5ed15f 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -187,7 +187,7 @@
sp<ANativeWindow> mNativeWindow;
sp<DisplaySurface> mDisplaySurface;
- RE::Surface mSurface;
+ std::unique_ptr<RE::Surface> mSurface;
int mDisplayWidth;
int mDisplayHeight;
mutable uint32_t mPageFlipCount;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 067a09f..78dd40b 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -719,7 +719,7 @@
void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
float alpha) const {
- RenderEngine& engine(mFlinger->getRenderEngine());
+ auto& engine(mFlinger->getRenderEngine());
computeGeometry(renderArea, getBE().mMesh, false);
engine.setupFillWithColor(red, green, blue, alpha);
engine.drawMesh(getBE().mMesh);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c63399e..3671a2b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -90,7 +90,7 @@
hwc_color_t color;
} hwc;
struct {
- RenderEngine* renderEngine;
+ RE::RenderEngine* renderEngine;
Mesh* mesh;
} renderEngine;
};
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 34d968d..9ecf8ce 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -105,6 +105,8 @@
// ---------------------------------------------------------------------------
namespace android {
+namespace RE {
+namespace impl {
// ---------------------------------------------------------------------------
GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags)
@@ -379,7 +381,9 @@
}
// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace impl
+} // namespace RE
+} // namespace android
// ---------------------------------------------------------------------------
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index f3af547..6e86ea2 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -35,6 +35,9 @@
class Mesh;
class Texture;
+namespace RE {
+namespace impl {
+
class GLES20RenderEngine : public RenderEngine {
GLuint mProtectedTexName;
GLint mMaxViewportDims[2];
@@ -105,7 +108,9 @@
};
// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace impl
+} // namespace RE
+} // namespace android
// ---------------------------------------------------------------------------
#endif /* SF_GLES20RENDERENGINE_H_ */
diff --git a/services/surfaceflinger/RenderEngine/Image.cpp b/services/surfaceflinger/RenderEngine/Image.cpp
index 1f8e75a..0d06422 100644
--- a/services/surfaceflinger/RenderEngine/Image.cpp
+++ b/services/surfaceflinger/RenderEngine/Image.cpp
@@ -26,6 +26,10 @@
namespace android {
namespace RE {
+Image::~Image() = default;
+
+namespace impl {
+
Image::Image(const RenderEngine& engine) : mEGLDisplay(engine.getEGLDisplay()) {}
Image::~Image() {
@@ -83,5 +87,6 @@
return true;
}
+} // namespace impl
} // namespace RE
} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/Image.h b/services/surfaceflinger/RenderEngine/Image.h
index f55aa59..1ae7e09 100644
--- a/services/surfaceflinger/RenderEngine/Image.h
+++ b/services/surfaceflinger/RenderEngine/Image.h
@@ -24,30 +24,39 @@
struct ANativeWindowBuffer;
namespace android {
-
-class RenderEngine;
-
namespace RE {
class Image {
public:
- Image(const RenderEngine& engine);
- ~Image();
+ virtual ~Image() = 0;
+ virtual bool setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected,
+ int32_t cropWidth, int32_t cropHeight) = 0;
+};
+
+namespace impl {
+
+class RenderEngine;
+
+class Image : public RE::Image {
+public:
+ explicit Image(const RenderEngine& engine);
+ ~Image() override;
Image(const Image&) = delete;
Image& operator=(const Image&) = delete;
bool setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, int32_t cropWidth,
- int32_t cropHeight);
+ int32_t cropHeight) override;
private:
// methods internal to RenderEngine
- friend class android::RenderEngine;
+ friend class RenderEngine;
EGLSurface getEGLImage() const { return mEGLImage; }
EGLDisplay mEGLDisplay;
EGLImageKHR mEGLImage = EGL_NO_IMAGE_KHR;
};
+} // namespace impl
} // namespace RE
} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 22016ed..4c878ae 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -37,8 +37,13 @@
// ---------------------------------------------------------------------------
namespace android {
+namespace RE {
// ---------------------------------------------------------------------------
+RenderEngine::~RenderEngine() = default;
+
+namespace impl {
+
std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featureFlags) {
// initialize EGL for the default display
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -137,9 +142,7 @@
bool RenderEngine::overrideUseContextPriorityFromConfig(bool useContextPriority) {
OptionalBool ret;
- ISurfaceFlingerConfigs::getService()->useContextPriority([&ret](OptionalBool b) {
- ret = b;
- });
+ ISurfaceFlingerConfigs::getService()->useContextPriority([&ret](OptionalBool b) { ret = b; });
if (ret.specified) {
return ret.value;
} else {
@@ -177,7 +180,22 @@
return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
}
-bool RenderEngine::setCurrentSurface(const RE::Surface& surface) {
+std::unique_ptr<RE::Surface> RenderEngine::createSurface() {
+ return std::make_unique<Surface>(*this);
+}
+
+std::unique_ptr<RE::Image> RenderEngine::createImage() {
+ return std::make_unique<Image>(*this);
+}
+
+bool RenderEngine::setCurrentSurface(const android::RE::Surface& surface) {
+ // Note: RE::Surface is an abstract interface. This implementation only ever
+ // creates RE::impl::Surface's, so it is safe to just cast to the actual
+ // type.
+ return setCurrentSurface(static_cast<const android::RE::impl::Surface&>(surface));
+}
+
+bool RenderEngine::setCurrentSurface(const android::RE::impl::Surface& surface) {
bool success = true;
EGLSurface eglSurface = surface.getEGLSurface();
if (eglSurface != eglGetCurrentSurface(EGL_DRAW)) {
@@ -349,7 +367,14 @@
glDeleteTextures(count, names);
}
-void RenderEngine::bindExternalTextureImage(uint32_t texName, const RE::Image& image) {
+void RenderEngine::bindExternalTextureImage(uint32_t texName, const android::RE::Image& image) {
+ // Note: RE::Image is an abstract interface. This implementation only ever
+ // creates RE::impl::Image's, so it is safe to just cast to the actual type.
+ return bindExternalTextureImage(texName, static_cast<const android::RE::impl::Image&>(image));
+}
+
+void RenderEngine::bindExternalTextureImage(uint32_t texName,
+ const android::RE::impl::Image& image) {
const GLenum target = GL_TEXTURE_EXTERNAL_OES;
glBindTexture(target, texName);
@@ -375,34 +400,33 @@
// ---------------------------------------------------------------------------
-RenderEngine::BindNativeBufferAsFramebuffer::BindNativeBufferAsFramebuffer(
- RenderEngine& engine, ANativeWindowBuffer* buffer)
- : mEngine(engine) {
- mImage = eglCreateImageKHR(mEngine.mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
- buffer, nullptr);
- if (mImage == EGL_NO_IMAGE_KHR) {
- mStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+void RenderEngine::bindNativeBufferAsFrameBuffer(ANativeWindowBuffer* buffer,
+ RE::BindNativeBufferAsFramebuffer* bindHelper) {
+ bindHelper->mImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+ buffer, nullptr);
+ if (bindHelper->mImage == EGL_NO_IMAGE_KHR) {
+ bindHelper->mStatus = NO_MEMORY;
return;
}
- mEngine.bindImageAsFramebuffer(mImage, &mTexName, &mFbName, &mStatus);
+ uint32_t glStatus;
+ bindImageAsFramebuffer(bindHelper->mImage, &bindHelper->mTexName, &bindHelper->mFbName,
+ &glStatus);
- ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d",
- mStatus);
+ ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d",
+ glStatus);
+
+ bindHelper->mStatus = glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
}
-RenderEngine::BindNativeBufferAsFramebuffer::~BindNativeBufferAsFramebuffer() {
- if (mImage == EGL_NO_IMAGE_KHR) {
+void RenderEngine::unbindNativeBufferAsFrameBuffer(RE::BindNativeBufferAsFramebuffer* bindHelper) {
+ if (bindHelper->mImage == EGL_NO_IMAGE_KHR) {
return;
}
// back to main framebuffer
- mEngine.unbindFramebuffer(mTexName, mFbName);
- eglDestroyImageKHR(mEngine.mEGLDisplay, mImage);
-}
-
-status_t RenderEngine::BindNativeBufferAsFramebuffer::getStatus() const {
- return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
+ unbindFramebuffer(bindHelper->mTexName, bindHelper->mFbName);
+ eglDestroyImageKHR(mEGLDisplay, bindHelper->mImage);
}
// ---------------------------------------------------------------------------
@@ -564,5 +588,7 @@
}
// ---------------------------------------------------------------------------
-}; // namespace android
-// ---------------------------------------------------------------------------
+
+} // namespace impl
+} // namespace RE
+} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 67c0d1c..eacef38 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -44,91 +44,63 @@
class Texture;
namespace RE {
+
class Image;
class Surface;
-} // namespace RE
+class BindNativeBufferAsFramebuffer;
+
+namespace impl {
+class RenderEngine;
+}
class RenderEngine {
- enum GlesVersion {
- 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(EGLDisplay display, EGLConfig config, EGLContext ctxt);
-
- 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;
-
- static bool overrideUseContextPriorityFromConfig(bool useContextPriority);
-
-protected:
- RenderEngine();
-
public:
- virtual ~RenderEngine() = 0;
-
enum FeatureFlag {
WIDE_COLOR_SUPPORT = 1 << 0 // Platform has a wide color display
};
- static std::unique_ptr<RenderEngine> create(int hwcFormat, uint32_t featureFlags);
- static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
+ virtual ~RenderEngine() = 0;
- void primeCache() const;
+ virtual std::unique_ptr<RE::Surface> createSurface() = 0;
+ virtual std::unique_ptr<RE::Image> createImage() = 0;
+
+ virtual void primeCache() const = 0;
// dump the extension strings. always call the base class.
- virtual void dump(String8& result);
+ virtual void dump(String8& result) = 0;
- bool supportsImageCrop() const;
+ virtual bool supportsImageCrop() const = 0;
- bool isCurrent() const;
- bool setCurrentSurface(const RE::Surface& surface);
- void resetCurrentSurface();
+ virtual bool isCurrent() const = 0;
+ virtual bool setCurrentSurface(const RE::Surface& surface) = 0;
+ virtual void resetCurrentSurface() = 0;
- // synchronization
-
+ // helpers
// flush submits RenderEngine command stream for execution and returns a
// native fence fd that is signaled when the execution has completed. It
// returns -1 on errors.
- base::unique_fd flush();
+ virtual base::unique_fd flush() = 0;
// finish waits until RenderEngine command stream has been executed. It
// returns false on errors.
- bool finish();
+ virtual bool finish() = 0;
// waitFence inserts a wait on an external fence fd to RenderEngine
// command stream. It returns false on errors.
- bool waitFence(base::unique_fd fenceFd);
+ virtual bool waitFence(base::unique_fd fenceFd) = 0;
- // helpers
- 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);
+ virtual void clearWithColor(float red, float green, float blue, float alpha) = 0;
+ virtual void fillRegionWithColor(const Region& region, uint32_t height, float red, float green,
+ float blue, float alpha) = 0;
// common to all GL versions
- void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top);
- void disableScissor();
- void genTextures(size_t count, uint32_t* names);
- void deleteTextures(size_t count, uint32_t const* names);
- void bindExternalTextureImage(uint32_t texName, const RE::Image& image);
- void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels);
-
- class BindNativeBufferAsFramebuffer {
- RenderEngine& mEngine;
- EGLImageKHR mImage;
- uint32_t mTexName, mFbName;
- uint32_t mStatus;
-
- public:
- BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer);
- ~BindNativeBufferAsFramebuffer();
- int getStatus() const;
- };
+ virtual void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) = 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;
+ virtual void bindExternalTextureImage(uint32_t texName, const RE::Image& image) = 0;
+ virtual void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels) = 0;
+ virtual void bindNativeBufferAsFrameBuffer(ANativeWindowBuffer* buffer,
+ RE::BindNativeBufferAsFramebuffer* bindHelper) = 0;
+ virtual void unbindNativeBufferAsFrameBuffer(RE::BindNativeBufferAsFramebuffer* bindHelper) = 0;
// set-up
virtual void checkErrors() const;
@@ -145,7 +117,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 */) = 0;
virtual void disableTexturing() = 0;
virtual void disableBlending() = 0;
@@ -156,14 +128,123 @@
// queries
virtual size_t getMaxTextureSize() const = 0;
virtual size_t getMaxViewportDims() const = 0;
+};
+
+class BindNativeBufferAsFramebuffer {
+public:
+ BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer)
+ : mEngine(engine) {
+ mEngine.bindNativeBufferAsFrameBuffer(buffer, this);
+ }
+ ~BindNativeBufferAsFramebuffer() { mEngine.unbindNativeBufferAsFrameBuffer(this); }
+ status_t getStatus() const { return mStatus; }
+
+protected:
+ friend impl::RenderEngine;
+
+ RenderEngine& mEngine;
+ EGLImageKHR mImage;
+ uint32_t mTexName, mFbName;
+ status_t mStatus;
+};
+
+namespace impl {
+
+class Image;
+class Surface;
+
+class RenderEngine : public RE::RenderEngine {
+ enum GlesVersion {
+ 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(EGLDisplay display, EGLConfig config, EGLContext ctxt);
+
+ static bool overrideUseContextPriorityFromConfig(bool useContextPriority);
+
+protected:
+ RenderEngine();
+
+public:
+ virtual ~RenderEngine() = 0;
+
+ static std::unique_ptr<RenderEngine> create(int hwcFormat, uint32_t featureFlags);
+
+ static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
+
+ // RenderEngine interface implementation
+
+ std::unique_ptr<RE::Surface> createSurface() override;
+ std::unique_ptr<RE::Image> createImage() override;
+
+ void primeCache() const override;
+
+ // dump the extension strings. always call the base class.
+ void dump(String8& result) override;
+
+ bool supportsImageCrop() const override;
+
+ bool isCurrent() const;
+ bool setCurrentSurface(const RE::Surface& surface) override;
+ void resetCurrentSurface() override;
+
+ // synchronization
+
+ // flush submits RenderEngine command stream for execution and returns a
+ // native fence fd that is signaled when the execution has completed. It
+ // returns -1 on errors.
+ base::unique_fd flush() override;
+ // finish waits until RenderEngine command stream has been executed. It
+ // returns false on errors.
+ bool finish() override;
+ // waitFence inserts a wait on an external fence fd to RenderEngine
+ // command stream. It returns false on errors.
+ bool waitFence(base::unique_fd fenceFd) override;
+
+ // helpers
+ void clearWithColor(float red, float green, float blue, float alpha) override;
+ void fillRegionWithColor(const Region& region, uint32_t height, float red, float green,
+ float blue, float alpha) override;
+
+ // common to all GL versions
+ void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) override;
+ void disableScissor() override;
+ void genTextures(size_t count, uint32_t* names) override;
+ void deleteTextures(size_t count, uint32_t const* names) override;
+ void bindExternalTextureImage(uint32_t texName, const RE::Image& image) override;
+ void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels) override;
+
+ void checkErrors() const override;
+
+ mat4 setupColorTransform(const mat4& /* colorTransform */) override { return mat4(); }
// internal to RenderEngine
EGLDisplay getEGLDisplay() const;
EGLConfig getEGLConfig() const;
+
+ // Common implementation
+ bool setCurrentSurface(const RE::impl::Surface& surface);
+ void bindExternalTextureImage(uint32_t texName, const RE::impl::Image& image);
+
+ void bindNativeBufferAsFrameBuffer(ANativeWindowBuffer* buffer,
+ RE::BindNativeBufferAsFramebuffer* bindHelper) override;
+ void unbindNativeBufferAsFrameBuffer(RE::BindNativeBufferAsFramebuffer* bindHelper) override;
+
+ // Overriden by each specialization
+ 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;
};
-// ---------------------------------------------------------------------------
-}; // namespace android
-// ---------------------------------------------------------------------------
+} // namespace impl
+} // namespace RE
+} // namespace android
#endif /* SF_RENDERENGINE_H_ */
diff --git a/services/surfaceflinger/RenderEngine/Surface.cpp b/services/surfaceflinger/RenderEngine/Surface.cpp
index a23d9fb..3c29e4b 100644
--- a/services/surfaceflinger/RenderEngine/Surface.cpp
+++ b/services/surfaceflinger/RenderEngine/Surface.cpp
@@ -23,6 +23,10 @@
namespace android {
namespace RE {
+Surface::~Surface() = default;
+
+namespace impl {
+
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
@@ -102,5 +106,6 @@
return querySurface(EGL_HEIGHT);
}
+} // namespace impl
} // namespace RE
} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/Surface.h b/services/surfaceflinger/RenderEngine/Surface.h
index 8b10be9..d4d3d8c 100644
--- a/services/surfaceflinger/RenderEngine/Surface.h
+++ b/services/surfaceflinger/RenderEngine/Surface.h
@@ -23,39 +23,60 @@
struct ANativeWindow;
namespace android {
-
-class RenderEngine;
-
namespace RE {
class Surface {
public:
+ virtual ~Surface() = 0;
+
+ virtual void setCritical(bool enable) = 0;
+ virtual void setAsync(bool enable) = 0;
+
+ virtual void setNativeWindow(ANativeWindow* window) = 0;
+ virtual void swapBuffers() const = 0;
+
+ virtual int32_t queryRedSize() const = 0;
+ virtual int32_t queryGreenSize() const = 0;
+ virtual int32_t queryBlueSize() const = 0;
+ virtual int32_t queryAlphaSize() const = 0;
+
+ virtual int32_t queryWidth() const = 0;
+ virtual int32_t queryHeight() const = 0;
+};
+
+namespace impl {
+
+class RenderEngine;
+
+class Surface final : public RE::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; }
+ // RE::Surface implementation
+ void setCritical(bool enable) override { mCritical = enable; }
+ void setAsync(bool enable) override { mAsync = enable; }
- void setNativeWindow(ANativeWindow* window);
- void swapBuffers() const;
+ void setNativeWindow(ANativeWindow* window) override;
+ void swapBuffers() const override;
- int32_t queryRedSize() const;
- int32_t queryGreenSize() const;
- int32_t queryBlueSize() const;
- int32_t queryAlphaSize() const;
+ int32_t queryRedSize() const override;
+ int32_t queryGreenSize() const override;
+ int32_t queryBlueSize() const override;
+ int32_t queryAlphaSize() const override;
- int32_t queryWidth() const;
- int32_t queryHeight() const;
+ int32_t queryWidth() const override;
+ int32_t queryHeight() const override;
private:
EGLint queryConfig(EGLint attrib) const;
EGLint querySurface(EGLint attrib) const;
// methods internal to RenderEngine
- friend class android::RenderEngine;
+ friend class RenderEngine;
bool getAsync() const { return mAsync; }
EGLSurface getEGLSurface() const { return mEGLSurface; }
@@ -69,5 +90,6 @@
EGLSurface mEGLSurface = EGL_NO_SURFACE;
};
+} // namespace impl
} // namespace RE
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1380b01..7ad13e3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -410,12 +410,11 @@
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
class MessageDestroyGLTexture : public MessageBase {
- RenderEngine& engine;
+ RE::RenderEngine& engine;
uint32_t texture;
public:
- MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
- : engine(engine), texture(texture) {
- }
+ MessageDestroyGLTexture(RE::RenderEngine& engine, uint32_t texture)
+ : engine(engine), texture(texture) {}
virtual bool handler() {
engine.deleteTextures(1, &texture);
return true;
@@ -587,8 +586,11 @@
mEventQueue.setEventThread(mSFEventThread.get());
// Get a RenderEngine for the given display / config (can't fail)
- getBE().mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
- hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);
+ getBE().mRenderEngine =
+ RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
+ hasWideColorDisplay
+ ? RE::RenderEngine::WIDE_COLOR_SUPPORT
+ : 0);
LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
@@ -1473,7 +1475,7 @@
// and draw the dirty region
const int32_t height = hw->getHeight();
- RenderEngine& engine(getRenderEngine());
+ auto& engine(getRenderEngine());
engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
hw->swapBuffers(getHwComposer());
@@ -2856,7 +2858,7 @@
void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const {
const int32_t height = displayDevice->getHeight();
- RenderEngine& engine(getRenderEngine());
+ auto& engine(getRenderEngine());
engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
}
@@ -4518,7 +4520,7 @@
bool useIdentityTransform) {
ATRACE_CALL();
- RenderEngine& engine(getRenderEngine());
+ auto& engine(getRenderEngine());
// get screen geometry
const auto raWidth = renderArea.getWidth();
@@ -4597,7 +4599,7 @@
// this binds the given EGLImage as a framebuffer for the
// duration of this scope.
- RenderEngine::BindNativeBufferAsFramebuffer bufferBond(getRenderEngine(), buffer);
+ RE::BindNativeBufferAsFramebuffer bufferBond(getRenderEngine(), buffer);
if (bufferBond.getStatus() != NO_ERROR) {
ALOGE("got ANWB binding error while taking screenshot");
return INVALID_OPERATION;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 19dd059..a17eb70 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -83,16 +83,19 @@
// ---------------------------------------------------------------------------
class Client;
-class DisplayEventConnection;
-class EventThread;
-class Layer;
class ColorLayer;
-class Surface;
-class RenderEngine;
+class DisplayEventConnection;
class EventControlThread;
-class VSyncSource;
+class EventThread;
class InjectVSyncSource;
+class Layer;
+class Surface;
class SurfaceFlingerBE;
+class VSyncSource;
+
+namespace RE {
+class RenderEngine;
+}
typedef std::function<void(const LayerVector::Visitor&)> TraverseLayersFunction;
@@ -139,7 +142,7 @@
const std::string mHwcServiceName; // "default" for real use, something else for testing.
// constant members (no synchronization needed for access)
- std::unique_ptr<RenderEngine> mRenderEngine;
+ std::unique_ptr<RE::RenderEngine> mRenderEngine;
EGLContext mEGLContext;
EGLDisplay mEGLDisplay;
@@ -301,9 +304,7 @@
// TODO: this should be made accessible only to HWComposer
const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id);
- RenderEngine& getRenderEngine() const {
- return *getBE().mRenderEngine;
- }
+ RE::RenderEngine& getRenderEngine() const { return *getBE().mRenderEngine; }
bool authenticateSurfaceTextureLocked(
const sp<IGraphicBufferProducer>& bufferProducer) const;