diff options
18 files changed, 336 insertions, 171 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4d4c9fcc3d..3dbc136205 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -200,7 +200,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, 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 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT 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 4d9b43f52e..46ec0e322b 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 @@ namespace android { 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 @@ status_t BufferLayerConsumer::bindTextureImageLocked() { 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 BufferLayerConsumer::bindTextureImageLocked() { 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 @@ void BufferLayerConsumer::dumpLocked(String8& result, const char* prefix) const 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 @@ status_t BufferLayerConsumer::Image::createIfNeeded(const Rect& imageCrop) { 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 a0272b3622..11048d8df8 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 @@ namespace android { 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 @@ public: // 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 @@ private: // 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 @@ private: 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 @@ private: // 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 10e77903ba..80a90a7d31 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -48,7 +48,7 @@ void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */, 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 cf70529b53..d40666e6f1 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -84,7 +84,7 @@ DisplayDevice::DisplayDevice( mHwcDisplayId(hwcId), mDisplayToken(displayToken), mDisplaySurface(displaySurface), - mSurface{flinger->getRenderEngine()}, + mSurface{flinger->getRenderEngine().createSurface()}, mDisplayWidth(), mDisplayHeight(), mPageFlipCount(), @@ -106,11 +106,11 @@ DisplayDevice::DisplayDevice( /* * 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 @@ status_t DisplayDevice::prepareFrame(HWComposer& hwc) { 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 @@ void DisplayDevice::onSwapBuffersCompleted() const { } bool DisplayDevice::makeCurrent() const { - bool success = mFlinger->getRenderEngine().setCurrentSurface(mSurface); + bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface); setViewportAndProjection(); return success; } @@ -360,14 +360,14 @@ status_t DisplayDevice::orientationToTransfrom( 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 @@ void DisplayDevice::dump(String8& result) const { "(%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 a4706701a8..d5ed15fa28 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -187,7 +187,7 @@ private: 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 067a09fb5d..78dd40b32f 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -719,7 +719,7 @@ void Layer::draw(const RenderArea& renderArea) const { 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 c63399e876..3671a2bb32 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -90,7 +90,7 @@ struct CompositionInfo { 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 34d968df6b..9ecf8ce2e7 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -105,6 +105,8 @@ void writePPM(const char* basename, GLuint width, GLuint height) { // --------------------------------------------------------------------------- namespace android { +namespace RE { +namespace impl { // --------------------------------------------------------------------------- GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags) @@ -379,7 +381,9 @@ void GLES20RenderEngine::dump(String8& result) { } // --------------------------------------------------------------------------- -}; // 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 f3af5479c6..6e86ea2680 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -35,6 +35,9 @@ class String8; class Mesh; class Texture; +namespace RE { +namespace impl { + class GLES20RenderEngine : public RenderEngine { GLuint mProtectedTexName; GLint mMaxViewportDims[2]; @@ -105,7 +108,9 @@ protected: }; // --------------------------------------------------------------------------- -}; // 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 1f8e75a0ae..0d06422a41 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 @@ bool Image::setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, return true; } +} // namespace impl } // namespace RE } // namespace android diff --git a/services/surfaceflinger/RenderEngine/Image.h b/services/surfaceflinger/RenderEngine/Image.h index f55aa59a8a..1ae7e09cba 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 22016edd85..4c878aee31 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -37,8 +37,13 @@ extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy // --------------------------------------------------------------------------- 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 @@ std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featu 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 @@ bool RenderEngine::isCurrent() const { 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 @@ void RenderEngine::deleteTextures(size_t count, uint32_t const* names) { 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 @@ void RenderEngine::dump(String8& result) { // --------------------------------------------------------------------------- -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 @@ void RenderEngine::primeCache() const { } // --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- + +} // namespace impl +} // namespace RE +} // namespace android diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index 67c0d1c139..eacef384b7 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -44,91 +44,63 @@ class Mesh; class Texture; namespace RE { + class Image; class Surface; -} // namespace RE +class BindNativeBufferAsFramebuffer; -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(); +namespace impl { +class RenderEngine; +} +class 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; - // dump the extension strings. always call the base class. - virtual void dump(String8& result); + virtual void primeCache() const = 0; - bool supportsImageCrop() const; + // dump the extension strings. always call the base class. + virtual void dump(String8& result) = 0; - bool isCurrent() const; - bool setCurrentSurface(const RE::Surface& surface); - void resetCurrentSurface(); + virtual bool supportsImageCrop() const = 0; - // synchronization + virtual bool isCurrent() const = 0; + virtual bool setCurrentSurface(const RE::Surface& surface) = 0; + virtual void resetCurrentSurface() = 0; + // 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 @@ public: 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 @@ public: // 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 a23d9fbb4e..3c29e4b2ea 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 @@ int32_t Surface::queryHeight() const { 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 8b10be9303..d4d3d8c0f5 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 @@ private: EGLSurface mEGLSurface = EGL_NO_SURFACE; }; +} // namespace impl } // namespace RE } // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1380b01a1c..7ad13e3ef2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -410,12 +410,11 @@ void SurfaceFlinger::bootFinished() 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 @@ void SurfaceFlinger::init() { 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 @@ void SurfaceFlinger::doDebugFlashRegions() // 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 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev 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 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, bool useIdentityTransform) { ATRACE_CALL(); - RenderEngine& engine(getRenderEngine()); + auto& engine(getRenderEngine()); // get screen geometry const auto raWidth = renderArea.getWidth(); @@ -4597,7 +4599,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea, // 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 19dd059e97..a17eb70882 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -83,16 +83,19 @@ namespace android { // --------------------------------------------------------------------------- class Client; +class ColorLayer; class DisplayEventConnection; +class EventControlThread; class EventThread; +class InjectVSyncSource; class Layer; -class ColorLayer; class Surface; -class RenderEngine; -class EventControlThread; -class VSyncSource; -class InjectVSyncSource; class SurfaceFlingerBE; +class VSyncSource; + +namespace RE { +class RenderEngine; +} typedef std::function<void(const LayerVector::Visitor&)> TraverseLayersFunction; @@ -139,7 +142,7 @@ public: 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 @@ public: // 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; |