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/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