Add ExternalTexture class into RenderEngine interface
ExternalTexture is an RAII structure that wraps raw GraphicBuffers that
are passed into RenderEngine. ExternalTexture's role is to help with
managing GPU resources of GraphicBuffers by mapping buffers into
textures, EGLImages, or AutoBackendTextures depending on the
RenderEngine backend. Under the hood, mapExternalTextureBuffer and
unmapExternalTextureBuffer (renamed from cacheExternalTextureBuffer and
unbindExternalTextureBuffer respectively) are used to help tie
resource management to the ExternalTexture lifetime.
The main motivation for this is that currently managing buffer
lifecycle has historically been errorprone and caused memory leaks, so
this improves code health.
As part of this:
* mapExternalTextureBuffer and unmapExternalTextureBuffer
are now protected methods, and are never called outside of RenderEngine
with the exception of creating and destroying ExternalTextures.
* Because GLESRenderEngine's output buffers are cached differently from
Skia RenderEngine, if there are output-only buffers then disable the
mapExternalTextureBuffer calls whenever GLESRenderEngine is used.
* Custom RAII classes in the Planner and in BufferLayerConsumer are now
removed since they're subsumed by ExternalTexture
* RenderSurface now controls its own management of ExternalTextures in a
small queue
* cleanFramebufferCache is now unimplemented for Skia, because
ExternalTextures are now deleted whenever a RenderSurface is deleted.
Bug: 180767535
Test: libsurfaceflinger_unittest
Test: libcompositionengine_test
Test: librenderengine_test
Test: Simulate virtual displays
Test: Screen reotation
Test: Movie playback on Google TV
Test: Force GPU composition
Test: screenshot
Change-Id: I222c71e6e1c67485cdeac49e2cb829289af9efec
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index ec39137..f395ab4 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -48,6 +48,7 @@
name: "librenderengine_sources",
srcs: [
"Description.cpp",
+ "ExternalTexture.cpp",
"Mesh.cpp",
"RenderEngine.cpp",
"Texture.cpp",
diff --git a/libs/renderengine/ExternalTexture.cpp b/libs/renderengine/ExternalTexture.cpp
new file mode 100644
index 0000000..eabff58
--- /dev/null
+++ b/libs/renderengine/ExternalTexture.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <renderengine/ExternalTexture.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/GraphicBuffer.h>
+
+#include "log/log_main.h"
+
+namespace android::renderengine {
+
+ExternalTexture::ExternalTexture(const sp<GraphicBuffer>& buffer, RenderEngine& renderEngine,
+ uint32_t usage)
+ : mBuffer(buffer), mRenderEngine(renderEngine) {
+ LOG_ALWAYS_FATAL_IF(buffer == nullptr,
+ "Attempted to bind a null buffer to an external texture!");
+ // GLESRenderEngine has a separate texture cache for output buffers,
+ if (usage == Usage::WRITEABLE &&
+ (mRenderEngine.getRenderEngineType() == RenderEngine::RenderEngineType::GLES ||
+ mRenderEngine.getRenderEngineType() == RenderEngine::RenderEngineType::THREADED)) {
+ return;
+ }
+ mRenderEngine.mapExternalTextureBuffer(mBuffer, usage & Usage::WRITEABLE);
+}
+
+ExternalTexture::~ExternalTexture() {
+ mRenderEngine.unmapExternalTextureBuffer(mBuffer);
+}
+
+} // namespace android::renderengine
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index a2963a7..d87315f 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -746,7 +746,8 @@
return;
}
-void GLESRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+void GLESRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
+ bool /*isRenderable*/) {
ATRACE_CALL();
mImageManager->cacheAsync(buffer, nullptr);
}
@@ -797,8 +798,8 @@
return NO_ERROR;
}
-void GLESRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
- mImageManager->releaseAsync(bufferId, nullptr);
+void GLESRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+ mImageManager->releaseAsync(buffer->getId(), nullptr);
}
std::shared_ptr<ImageManager::Barrier> GLESRenderEngine::unbindExternalTextureBufferForTesting(
@@ -1102,7 +1103,7 @@
status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const sp<GraphicBuffer>& buffer,
+ const std::shared_ptr<ExternalTexture>& buffer,
const bool useFramebufferCache, base::unique_fd&& bufferFence,
base::unique_fd* drawFence) {
ATRACE_CALL();
@@ -1125,7 +1126,7 @@
return BAD_VALUE;
}
- validateOutputBufferUsage(buffer);
+ validateOutputBufferUsage(buffer->getBuffer());
std::unique_ptr<BindNativeBufferAsFramebuffer> fbo;
// Gathering layers that requested blur, we'll need them to decide when to render to an
@@ -1142,11 +1143,13 @@
if (blurLayersSize == 0) {
fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
- buffer.get()->getNativeBuffer(),
+ buffer->getBuffer()
+ .get()
+ ->getNativeBuffer(),
useFramebufferCache);
if (fbo->getStatus() != NO_ERROR) {
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
- buffer->handle);
+ buffer->getBuffer()->handle);
checkErrors();
return fbo->getStatus();
}
@@ -1157,7 +1160,7 @@
mBlurFilter->setAsDrawTarget(display, blurLayers.front()->backgroundBlurRadius);
if (status != NO_ERROR) {
ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).",
- buffer->handle);
+ buffer->getBuffer()->handle);
checkErrors();
return status;
}
@@ -1194,7 +1197,7 @@
auto status = mBlurFilter->prepare();
if (status != NO_ERROR) {
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
- buffer->handle);
+ buffer->getBuffer()->handle);
checkErrors("Can't render first blur pass");
return status;
}
@@ -1203,6 +1206,7 @@
// Done blurring, time to bind the native FBO and render our blur onto it.
fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
buffer.get()
+ ->getBuffer()
->getNativeBuffer(),
useFramebufferCache);
status = fbo->getStatus();
@@ -1215,7 +1219,7 @@
}
if (status != NO_ERROR) {
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
- buffer->handle);
+ buffer->getBuffer()->handle);
checkErrors("Can't bind native framebuffer");
return status;
}
@@ -1223,7 +1227,7 @@
status = mBlurFilter->render(blurLayersSize > 1);
if (status != NO_ERROR) {
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
- buffer->handle);
+ buffer->getBuffer()->handle);
checkErrors("Can't render blur filter");
return status;
}
@@ -1250,7 +1254,7 @@
disableTexture = false;
isOpaque = layer->source.buffer.isOpaque;
- sp<GraphicBuffer> gBuf = layer->source.buffer.buffer;
+ sp<GraphicBuffer> gBuf = layer->source.buffer.buffer->getBuffer();
validateInputBufferUsage(gBuf);
bindExternalTextureBuffer(layer->source.buffer.textureName, gBuf,
layer->source.buffer.fence);
@@ -1274,7 +1278,7 @@
// Do not cache protected EGLImage, protected memory is limited.
if (gBuf->getUsage() & GRALLOC_USAGE_PROTECTED) {
- unbindExternalTextureBuffer(gBuf->getId());
+ unmapExternalTextureBuffer(gBuf);
}
}
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index cd7a86b..e7ed9c0 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -60,16 +60,14 @@
void primeCache() override;
void genTextures(size_t count, uint32_t* names) override;
void deleteTextures(size_t count, uint32_t const* names) override;
- void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
- void unbindExternalTextureBuffer(uint64_t bufferId) EXCLUDES(mRenderingMutex);
-
bool isProtected() const override { return mInProtectedContext; }
bool supportsProtectedContent() const override;
bool useProtectedContext(bool useProtectedContext) override;
status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
- base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache, base::unique_fd&& bufferFence,
+ base::unique_fd* drawFence) override;
bool cleanupPostRender(CleanupMode mode) override;
int getContextPriority() override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
@@ -105,6 +103,9 @@
EXCLUDES(mFramebufferImageCacheMutex);
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
+ void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable)
+ EXCLUDES(mRenderingMutex);
+ void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
private:
friend class BindNativeBufferAsFramebuffer;
diff --git a/libs/renderengine/include/renderengine/ExternalTexture.h b/libs/renderengine/include/renderengine/ExternalTexture.h
new file mode 100644
index 0000000..07f0833
--- /dev/null
+++ b/libs/renderengine/include/renderengine/ExternalTexture.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <ui/GraphicBuffer.h>
+
+namespace android::renderengine {
+
+class RenderEngine;
+
+/**
+ * Manages GPU image resources on behalf of clients using RenderEngine.
+ *
+ * Clients of RenderEngine are required to wrap their GraphicBuffer objects as an ExternalTexture,
+ * which is then mapped into GPU resources required by RenderEngine. When a client no longer needs
+ * to use the GraphicBuffer as input into RenderEngine::drawLayers, then the client should delete
+ * their ExternalTexture so that resources may be freed.
+ */
+class ExternalTexture {
+public:
+ // Usage specifies the rendering intent for the buffer.
+ enum Usage : uint32_t {
+ // When a buffer is not READABLE but is WRITEABLE, then GLESRenderEngine will use that as a
+ // hint to load the buffer into a separate cache
+ READABLE = 1 << 0,
+
+ // The buffer needs to be mapped as a 2D texture if set, otherwise must be mapped as an
+ // external texture
+ WRITEABLE = 1 << 1,
+ };
+ // Creates an ExternalTexture for the provided buffer and RenderEngine instance, with the given
+ // usage hint of type Usage.
+ ExternalTexture(const sp<GraphicBuffer>& buffer, RenderEngine& renderEngine, uint32_t usage);
+
+ ~ExternalTexture();
+
+ // Retrieves the buffer that is bound to this texture.
+ const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
+
+private:
+ sp<GraphicBuffer> mBuffer;
+ RenderEngine& mRenderEngine;
+ DISALLOW_COPY_AND_ASSIGN(ExternalTexture);
+};
+
+} // namespace android::renderengine
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index 7661233..c54c5ba 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -16,11 +16,9 @@
#pragma once
-#include <iosfwd>
-
#include <math/mat4.h>
#include <math/vec3.h>
-#include <renderengine/Texture.h>
+#include <renderengine/ExternalTexture.h>
#include <ui/BlurRegion.h>
#include <ui/Fence.h>
#include <ui/FloatRect.h>
@@ -31,6 +29,8 @@
#include <ui/StretchEffect.h>
#include <ui/Transform.h>
+#include <iosfwd>
+
namespace android {
namespace renderengine {
@@ -39,7 +39,7 @@
// Buffer containing the image that we will render.
// If buffer == nullptr, then the rest of the fields in this struct will be
// ignored.
- sp<GraphicBuffer> buffer = nullptr;
+ std::shared_ptr<ExternalTexture> buffer = nullptr;
// Fence that will fire when the buffer is ready to be bound.
sp<Fence> fence = nullptr;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 8dd98c3..c8a0f0a 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -17,19 +17,20 @@
#ifndef SF_RENDERENGINE_H_
#define SF_RENDERENGINE_H_
-#include <stdint.h>
-#include <sys/types.h>
-#include <memory>
-
#include <android-base/unique_fd.h>
#include <math/mat4.h>
#include <renderengine/DisplaySettings.h>
+#include <renderengine/ExternalTexture.h>
#include <renderengine/Framebuffer.h>
#include <renderengine/Image.h>
#include <renderengine/LayerSettings.h>
+#include <stdint.h>
+#include <sys/types.h>
#include <ui/GraphicTypes.h>
#include <ui/Transform.h>
+#include <memory>
+
/**
* Allows to set RenderEngine backend to GLES (default) or SkiaGL (NOT yet supported).
*/
@@ -51,6 +52,7 @@
namespace renderengine {
+class ExternalTexture;
class Image;
class Mesh;
class Texture;
@@ -104,23 +106,6 @@
virtual void genTextures(size_t count, uint32_t* names) = 0;
virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
- // Caches Image resources for this buffer, but does not bind the buffer to
- // a particular texture.
- // Note that work is deferred to an additional thread, i.e. this call
- // is made asynchronously, but the caller can expect that cache/unbind calls
- // are performed in a manner that's conflict serializable, i.e. unbinding
- // a buffer should never occur before binding the buffer if the caller
- // called {bind, cache}ExternalTextureBuffer before calling unbind.
- virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0;
- // Removes internal resources referenced by the bufferId. This method should be
- // invoked when the caller will no longer hold a reference to a GraphicBuffer
- // and needs to clean up its resources.
- // Note that work is deferred to an additional thread, i.e. this call
- // is made asynchronously, but the caller can expect that cache/unbind calls
- // are performed in a manner that's conflict serializable, i.e. unbinding
- // a buffer should never occur before binding the buffer if the caller
- // called {bind, cache}ExternalTextureBuffer before calling unbind.
- virtual void unbindExternalTextureBuffer(uint64_t bufferId) = 0;
enum class CleanupMode {
CLEAN_OUTPUT_RESOURCES,
@@ -191,8 +176,9 @@
// now, this always returns NO_ERROR.
virtual status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
- base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0;
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache, base::unique_fd&& bufferFence,
+ base::unique_fd* drawFence) = 0;
virtual void cleanFramebufferCache() = 0;
// Returns the priority this context was actually created with. Note: this may not be
// the same as specified at context creation time, due to implementation limits on the
@@ -213,6 +199,31 @@
static void validateOutputBufferUsage(const sp<GraphicBuffer>&);
protected:
+ // Maps GPU resources for this buffer.
+ // Note that work may be deferred to an additional thread, i.e. this call
+ // is made asynchronously, but the caller can expect that map/unmap calls
+ // are performed in a manner that's conflict serializable, i.e. unmapping
+ // a buffer should never occur before binding the buffer if the caller
+ // called mapExternalTextureBuffer before calling unmap.
+ // Note also that if the buffer contains protected content, then mapping those GPU resources may
+ // be deferred until the buffer is really used for drawing. This is because typical SoCs that
+ // support protected memory only support a limited amount, so optimisitically mapping protected
+ // memory may be too burdensome. If a buffer contains protected content and the RenderEngine
+ // implementation supports protected context, then GPU resources may be mapped into both the
+ // protected and unprotected contexts.
+ // If the buffer may ever be written to by RenderEngine, then isRenderable must be true.
+ virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) = 0;
+ // Unmaps GPU resources used by this buffer. This method should be
+ // invoked when the caller will no longer hold a reference to a GraphicBuffer
+ // and needs to clean up its resources.
+ // Note that if there are multiple callers holding onto the same buffer, then the buffer's
+ // resources may be internally ref-counted to guard against use-after-free errors. Note that
+ // work may be deferred to an additional thread, i.e. this call is expected to be made
+ // asynchronously, but the caller can expect that map/unmap calls are performed in a manner
+ // that's conflict serializable, i.e. unmap a buffer should never occur before binding the
+ // buffer if the caller called mapExternalTextureBuffer before calling unmap.
+ virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0;
+ friend class ExternalTexture;
friend class threaded::RenderEngineThreaded;
const RenderEngineType mRenderEngineType;
};
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 228553d..27dbd1e 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -39,8 +39,6 @@
MOCK_METHOD1(dump, void(std::string&));
MOCK_METHOD2(genTextures, void(size_t, uint32_t*));
MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*));
- MOCK_METHOD1(cacheExternalTextureBuffer, void(const sp<GraphicBuffer>&));
- MOCK_METHOD1(unbindExternalTextureBuffer, void(uint64_t));
MOCK_METHOD1(drawMesh, void(const renderengine::Mesh&));
MOCK_CONST_METHOD0(getMaxTextureSize, size_t());
MOCK_CONST_METHOD0(getMaxViewportDims, size_t());
@@ -50,12 +48,17 @@
MOCK_METHOD1(cleanupPostRender, bool(CleanupMode mode));
MOCK_METHOD6(drawLayers,
status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&,
base::unique_fd*));
MOCK_METHOD0(cleanFramebufferCache, void());
MOCK_METHOD0(getContextPriority, int());
MOCK_METHOD0(supportsBackgroundBlur, bool());
MOCK_METHOD1(onPrimaryDisplaySizeChanged, void(ui::Size));
+
+protected:
+ // mock renderengine still needs to implement these, but callers should never need to call them.
+ void mapExternalTextureBuffer(const sp<GraphicBuffer>&, bool) {}
+ void unmapExternalTextureBuffer(const sp<GraphicBuffer>&) {}
};
} // namespace mock
diff --git a/libs/renderengine/skia/AutoBackendTexture.h b/libs/renderengine/skia/AutoBackendTexture.h
index bb75878..2d61cf8 100644
--- a/libs/renderengine/skia/AutoBackendTexture.h
+++ b/libs/renderengine/skia/AutoBackendTexture.h
@@ -21,9 +21,9 @@
#include <SkImage.h>
#include <SkSurface.h>
#include <sys/types.h>
+#include <ui/GraphicTypes.h>
#include "android-base/macros.h"
-#include "ui/GraphicTypes.h"
namespace android {
namespace renderengine {
@@ -41,13 +41,18 @@
// of shared ownership with Skia objects, so we wrap it here instead.
class LocalRef {
public:
- LocalRef() {}
+ LocalRef(AutoBackendTexture* texture) { setTexture(texture); }
~LocalRef() {
// Destroying the texture is the same as setting it to null
setTexture(nullptr);
}
+ AutoBackendTexture* getTexture() const { return mTexture; }
+
+ DISALLOW_COPY_AND_ASSIGN(LocalRef);
+
+ private:
// Sets the texture to locally ref-track.
void setTexture(AutoBackendTexture* texture) {
if (mTexture != nullptr) {
@@ -59,12 +64,6 @@
mTexture->ref();
}
}
-
- AutoBackendTexture* getTexture() const { return mTexture; }
-
- DISALLOW_COPY_AND_ASSIGN(LocalRef);
-
- private:
AutoBackendTexture* mTexture = nullptr;
};
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index 1db20c0..1c2b2fc 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -46,7 +46,7 @@
} // namespace
static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- sp<GraphicBuffer> dstBuffer) {
+ const std::shared_ptr<ExternalTexture>& dstTexture) {
// Somewhat arbitrary dimensions, but on screen and slightly shorter, based
// on actual use.
FloatRect rect(0, 0, display.physicalDisplay.width(), display.physicalDisplay.height() - 30);
@@ -73,7 +73,7 @@
auto layers = std::vector<const LayerSettings*>{&layer};
// The identity matrix will generate the fast shader
- renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache, base::unique_fd(),
+ renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd(),
nullptr);
// This matrix, which has different scales for x and y, will
// generate the slower (more general case) version, which has variants for translucent
@@ -86,13 +86,14 @@
// clang-format on
for (auto translucent : {false, true}) {
layer.shadow.casterIsTranslucent = translucent;
- renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- sp<GraphicBuffer> dstBuffer, sp<GraphicBuffer> srcBuffer) {
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -103,7 +104,7 @@
},
.source = PixelSource{.buffer =
Buffer{
- .buffer = srcBuffer,
+ .buffer = srcTexture,
.maxMasteringLuminance = 1000.f,
.maxContentLuminance = 1000.f,
}},
@@ -126,7 +127,7 @@
layer.source.buffer.isOpaque = isOpaque;
for (auto alpha : {half(.23999f), half(1.0f)}) {
layer.alpha = alpha;
- renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
@@ -135,7 +136,7 @@
}
static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- sp<GraphicBuffer> dstBuffer) {
+ const std::shared_ptr<ExternalTexture>& dstTexture) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -143,11 +144,11 @@
Geometry{
.boundaries = rect,
},
- .alpha = 1,
.source =
PixelSource{
.solidColor = half3(0.1f, 0.2f, 0.3f),
},
+ .alpha = 1,
};
auto layers = std::vector<const LayerSettings*>{&layer};
@@ -155,14 +156,14 @@
layer.geometry.positionTransform = transform;
for (float roundedCornersRadius : {0.0f, 0.05f, 50.f}) {
layer.geometry.roundedCornersRadius = roundedCornersRadius;
- renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
}
static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- sp<GraphicBuffer> dstBuffer) {
+ const std::shared_ptr<ExternalTexture>& dstTexture) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -176,7 +177,7 @@
auto layers = std::vector<const LayerSettings*>{&layer};
for (int radius : {9, 60}) {
layer.backgroundBlurRadius = radius;
- renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
@@ -214,6 +215,9 @@
sp<GraphicBuffer> dstBuffer =
new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
usage, "primeShaderCache_dst");
+
+ const auto dstTexture = std::make_shared<ExternalTexture>(dstBuffer, *renderengine,
+ ExternalTexture::Usage::WRITEABLE);
// This buffer will be the source for the call to drawImageLayers. Draw
// something to it as a placeholder for what an app draws. We should draw
// something, but the details are not important. Make use of the shadow layer drawing step
@@ -222,11 +226,16 @@
new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
usage, "drawImageLayer_src");
- drawSolidLayers(renderengine, display, dstBuffer);
- drawShadowLayers(renderengine, display, srcBuffer);
- drawBlurLayers(renderengine, display, dstBuffer);
+ const auto srcTexture =
+ std::make_shared<ExternalTexture>(srcBuffer, *renderengine,
+ ExternalTexture::Usage::READABLE |
+ ExternalTexture::Usage::WRITEABLE);
+
+ drawSolidLayers(renderengine, display, dstTexture);
+ drawShadowLayers(renderengine, display, srcTexture);
+ drawBlurLayers(renderengine, display, dstTexture);
// The majority of shaders are related to sampling images.
- drawImageLayers(renderengine, display, dstBuffer, srcBuffer);
+ drawImageLayers(renderengine, display, dstTexture, srcTexture);
// should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
@@ -234,12 +243,12 @@
sp<GraphicBuffer> externalBuffer =
new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
usageExternal, "primeShaderCache_external");
+ const auto externalTexture =
+ std::make_shared<ExternalTexture>(externalBuffer, *renderengine,
+ ExternalTexture::Usage::READABLE);
// TODO(b/184665179) doubles number of image shader compilations, but only somewhere
// between 6 and 8 will occur in real uses.
- drawImageLayers(renderengine, display, dstBuffer, externalBuffer);
- renderengine->unbindExternalTextureBuffer(externalBuffer->getId());
-
- renderengine->unbindExternalTextureBuffer(srcBuffer->getId());
+ drawImageLayers(renderengine, display, dstTexture, externalTexture);
const nsecs_t timeAfter = systemTime();
const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 3b2c7e5..e781584 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -329,8 +329,6 @@
}
SkiaGLRenderEngine::~SkiaGLRenderEngine() {
- cleanFramebufferCache();
-
std::lock_guard<std::mutex> lock(mRenderingMutex);
if (mBlurFilter) {
delete mBlurFilter;
@@ -484,7 +482,8 @@
sourceTransfer != destTransfer;
}
-void SkiaGLRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
+ bool isRenderable) {
// Only run this if RE is running on its own thread. This way the access to GL
// operations is guaranteed to be happening on the same thread.
if (mRenderEngineType != RenderEngineType::SKIA_GL_THREADED) {
@@ -505,25 +504,41 @@
auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
std::lock_guard<std::mutex> lock(mRenderingMutex);
- auto iter = cache.find(buffer->getId());
- if (iter != cache.end()) {
- ALOGV("Texture already exists in cache.");
- } else {
+ mGraphicBufferExternalRefs[buffer->getId()]++;
+
+ if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
- std::make_shared<AutoBackendTexture::LocalRef>();
- imageTextureRef->setTexture(
- new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), false));
+ std::make_shared<AutoBackendTexture::LocalRef>(
+ new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(),
+ isRenderable));
cache.insert({buffer->getId(), imageTextureRef});
}
// restore the original state of the protected context if necessary
useProtectedContext(protectedContextState);
}
-void SkiaGLRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
+void SkiaGLRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mRenderingMutex);
- mTextureCache.erase(bufferId);
- mProtectedTextureCache.erase(bufferId);
+ if (const auto& iter = mGraphicBufferExternalRefs.find(buffer->getId());
+ iter != mGraphicBufferExternalRefs.end()) {
+ if (iter->second == 0) {
+ ALOGW("Attempted to unmap GraphicBuffer <id: %" PRId64
+ "> from RenderEngine texture, but the "
+ "ref count was already zero!",
+ buffer->getId());
+ mGraphicBufferExternalRefs.erase(buffer->getId());
+ return;
+ }
+
+ iter->second--;
+
+ if (iter->second == 0) {
+ mTextureCache.erase(buffer->getId());
+ mProtectedTextureCache.erase(buffer->getId());
+ mGraphicBufferExternalRefs.erase(buffer->getId());
+ }
+ }
}
sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> shader,
@@ -621,8 +636,8 @@
status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const sp<GraphicBuffer>& buffer,
- const bool useFramebufferCache,
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool /*useFramebufferCache*/,
base::unique_fd&& bufferFence, base::unique_fd* drawFence) {
ATRACE_NAME("SkiaGL::drawLayers");
@@ -645,32 +660,18 @@
return BAD_VALUE;
}
- validateOutputBufferUsage(buffer);
+ validateOutputBufferUsage(buffer->getBuffer());
auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
- AHardwareBuffer_Desc bufferDesc;
- AHardwareBuffer_describe(buffer->toAHardwareBuffer(), &bufferDesc);
- std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef = nullptr;
- if (useFramebufferCache) {
- auto iter = cache.find(buffer->getId());
- if (iter != cache.end()) {
- ALOGV("Cache hit!");
- ATRACE_NAME("Cache hit");
- surfaceTextureRef = iter->second;
- }
- }
-
- if (surfaceTextureRef == nullptr || surfaceTextureRef->getTexture() == nullptr) {
- ATRACE_NAME("Cache miss");
- surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
- surfaceTextureRef->setTexture(
- new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), true));
- if (useFramebufferCache) {
- ALOGD("Adding to cache");
- cache.insert({buffer->getId(), surfaceTextureRef});
- }
+ std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef;
+ if (const auto& it = cache.find(buffer->getBuffer()->getId()); it != cache.end()) {
+ surfaceTextureRef = it->second;
+ } else {
+ surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
+ new AutoBackendTexture(grContext.get(), buffer->getBuffer()->toAHardwareBuffer(),
+ true));
}
const ui::Dataspace dstDataspace =
@@ -876,18 +877,22 @@
SkPaint paint;
if (layer->source.buffer.buffer) {
ATRACE_NAME("DrawImage");
- validateInputBufferUsage(layer->source.buffer.buffer);
+ validateInputBufferUsage(layer->source.buffer.buffer->getBuffer());
const auto& item = layer->source.buffer;
std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = nullptr;
- auto iter = cache.find(item.buffer->getId());
- if (iter != cache.end()) {
+
+ if (const auto& iter = cache.find(item.buffer->getBuffer()->getId());
+ iter != cache.end()) {
imageTextureRef = iter->second;
} else {
- imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
- imageTextureRef->setTexture(new AutoBackendTexture(grContext.get(),
- item.buffer->toAHardwareBuffer(),
- false));
- cache.insert({item.buffer->getId(), imageTextureRef});
+ // If we didn't find the image in the cache, then create a local ref but don't cache
+ // it. If we're using skia, we're guaranteed to run on a dedicated GPU thread so if
+ // we didn't find anything in the cache then we intentionally did not cache this
+ // buffer's resources.
+ imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
+ new AutoBackendTexture(grContext.get(),
+ item.buffer->getBuffer()->toAHardwareBuffer(),
+ false));
}
sk_sp<SkImage> image =
@@ -1200,15 +1205,6 @@
return eglCreatePbufferSurface(display, placeholderConfig, attributes.data());
}
-void SkiaGLRenderEngine::cleanFramebufferCache() {
- // TODO(b/180767535) Remove this method and use b/180767535 instead, which would allow
- // SF to control texture lifecycle more tightly rather than through custom hooks into RE.
- std::lock_guard<std::mutex> lock(mRenderingMutex);
- mRuntimeEffects.clear();
- mProtectedTextureCache.clear();
- mTextureCache.clear();
-}
-
int SkiaGLRenderEngine::getContextPriority() {
int value;
eglQueryContext(mEGLDisplay, mEGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value);
@@ -1281,6 +1277,12 @@
StringAppendF(&result, "Skia's Wrapped Objects:\n");
gpuReporter.logOutput(result, true);
+ StringAppendF(&result, "RenderEngine tracked buffers: %zu\n",
+ mGraphicBufferExternalRefs.size());
+ StringAppendF(&result, "Dumping buffer ids...\n");
+ for (const auto& [id, refCounts] : mGraphicBufferExternalRefs) {
+ StringAppendF(&result, "- 0x%" PRIx64 " - %d refs \n", id, refCounts);
+ }
StringAppendF(&result, "RenderEngine AHB/BackendTexture cache size: %zu\n",
mTextureCache.size());
StringAppendF(&result, "Dumping buffer ids...\n");
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 8e77c16..e71c560 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -23,6 +23,7 @@
#include <GrDirectContext.h>
#include <SkSurface.h>
#include <android-base/thread_annotations.h>
+#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <sys/types.h>
@@ -52,13 +53,12 @@
~SkiaGLRenderEngine() override EXCLUDES(mRenderingMutex);
void primeCache() override;
- void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
- void unbindExternalTextureBuffer(uint64_t bufferId) override;
status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
- base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
- void cleanFramebufferCache() override;
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache, base::unique_fd&& bufferFence,
+ base::unique_fd* drawFence) override;
+ void cleanFramebufferCache() override {}
int getContextPriority() override;
bool isProtected() const override { return mInProtectedContext; }
bool supportsProtectedContent() const override;
@@ -72,6 +72,8 @@
void dump(std::string& result) override;
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
+ void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
+ void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
private:
static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
@@ -114,7 +116,9 @@
const PixelFormat mDefaultPixelFormat;
const bool mUseColorManagement;
- // Cache of GL textures that we'll store per GraphicBuffer ID
+ // Number of external holders of ExternalTexture references, per GraphicBuffer ID.
+ std::unordered_map<uint64_t, int32_t> mGraphicBufferExternalRefs GUARDED_BY(mRenderingMutex);
+ // Cache of GL textures that we'll store per GraphicBuffer ID, sliced by GPU context.
std::unordered_map<uint64_t, std::shared_ptr<AutoBackendTexture::LocalRef>> mTextureCache
GUARDED_BY(mRenderingMutex);
std::unordered_map<uint64_t, std::shared_ptr<AutoBackendTexture::LocalRef>>
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index 51ef088..308c5ff 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -42,15 +42,12 @@
virtual void primeCache() override{};
virtual void genTextures(size_t /*count*/, uint32_t* /*names*/) override{};
virtual void deleteTextures(size_t /*count*/, uint32_t const* /*names*/) override{};
- virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/){};
- virtual void unbindExternalTextureBuffer(uint64_t /*bufferId*/){};
-
virtual bool isProtected() const override { return false; } // mInProtectedContext; }
virtual bool supportsProtectedContent() const override { return false; };
virtual bool useProtectedContext(bool /*useProtectedContext*/) override { return false; };
virtual status_t drawLayers(const DisplaySettings& /*display*/,
const std::vector<const LayerSettings*>& /*layers*/,
- const sp<GraphicBuffer>& /*buffer*/,
+ const std::shared_ptr<ExternalTexture>& /*buffer*/,
const bool /*useFramebufferCache*/,
base::unique_fd&& /*bufferFence*/,
base::unique_fd* /*drawFence*/) override {
@@ -60,6 +57,11 @@
virtual int getContextPriority() override { return 0; }
virtual void assertShadersCompiled(int numShaders) {}
virtual int reportShadersCompiled() { return 0; }
+
+protected:
+ virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/,
+ bool /*isRenderable*/) override;
+ virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/) override;
};
} // namespace skia
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 7846156..d63c88b 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -24,6 +24,7 @@
#include <cutils/properties.h>
#include <gtest/gtest.h>
+#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <sync/sync.h>
#include <ui/PixelFormat.h>
@@ -160,27 +161,42 @@
class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
public:
- static sp<GraphicBuffer> allocateDefaultBuffer() {
- return new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
- HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
- GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
- "output");
+ std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
+ return std::make_shared<
+ renderengine::
+ ExternalTexture>(new GraphicBuffer(DEFAULT_DISPLAY_WIDTH,
+ DEFAULT_DISPLAY_HEIGHT,
+ HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_SW_WRITE_OFTEN |
+ GRALLOC_USAGE_HW_RENDER |
+ GRALLOC_USAGE_HW_TEXTURE,
+ "output"),
+ *mRE,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
}
// Allocates a 1x1 buffer to fill with a solid color
- static sp<GraphicBuffer> allocateSourceBuffer(uint32_t width, uint32_t height) {
- return new GraphicBuffer(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
- GRALLOC_USAGE_HW_TEXTURE,
- "input");
+ std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
+ uint32_t height) {
+ return std::make_shared<
+ renderengine::
+ ExternalTexture>(new GraphicBuffer(width, height,
+ HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_SW_WRITE_OFTEN |
+ GRALLOC_USAGE_HW_TEXTURE,
+ "input"),
+ *mRE,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
}
RenderEngineTest() {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
- mBuffer = allocateDefaultBuffer();
}
~RenderEngineTest() {
@@ -211,20 +227,21 @@
}
uint8_t* pixels;
- mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
file << "P6\n";
- file << mBuffer->getWidth() << "\n";
- file << mBuffer->getHeight() << "\n";
+ file << mBuffer->getBuffer()->getWidth() << "\n";
+ file << mBuffer->getBuffer()->getHeight() << "\n";
file << 255 << "\n";
- std::vector<uint8_t> outBuffer(mBuffer->getWidth() * mBuffer->getHeight() * 3);
+ std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
+ mBuffer->getBuffer()->getHeight() * 3);
auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
- for (int32_t j = 0; j < mBuffer->getHeight(); j++) {
- const uint8_t* src = pixels + (mBuffer->getStride() * j) * 4;
- for (int32_t i = 0; i < mBuffer->getWidth(); i++) {
+ for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
+ const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
+ for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
// Only copy R, G and B components
outPtr[0] = src[0];
outPtr[1] = src[1];
@@ -235,7 +252,7 @@
}
}
file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
- mBuffer->unlock();
+ mBuffer->getBuffer()->unlock();
}
void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
@@ -262,13 +279,13 @@
void expectBufferColor(const Rect& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
uint8_t* pixels;
- mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
int32_t maxFails = 10;
int32_t fails = 0;
for (int32_t j = 0; j < region.getHeight(); j++) {
- const uint8_t* src =
- pixels + (mBuffer->getStride() * (region.top + j) + region.left) * 4;
+ const uint8_t* src = pixels +
+ (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
for (int32_t i = 0; i < region.getWidth(); i++) {
const uint8_t expected[4] = {r, g, b, a};
bool equal = colorCompare(src, expected);
@@ -289,7 +306,7 @@
break;
}
}
- mBuffer->unlock();
+ mBuffer->getBuffer()->unlock();
}
void expectAlpha(const Rect& rect, uint8_t a) {
@@ -387,7 +404,6 @@
base::unique_fd fence;
status_t status =
mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), &fence);
- mCurrentBuffer = mBuffer;
int fd = fence.release();
if (fd >= 0) {
@@ -397,7 +413,7 @@
ASSERT_EQ(NO_ERROR, status);
if (layers.size() > 0 && mGLESRE != nullptr) {
- ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId()));
+ ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
}
}
@@ -503,17 +519,11 @@
void initializeRenderEngine();
std::unique_ptr<renderengine::RenderEngine> mRE;
+ std::shared_ptr<renderengine::ExternalTexture> mBuffer;
// GLESRenderEngine for testing GLES-specific behavior.
// Owened by mRE, but this is downcasted.
renderengine::gl::GLESRenderEngine* mGLESRE = nullptr;
- // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to
- // be freed *after* RenderEngine is destroyed, so that the EGL image is
- // destroyed first.
- sp<GraphicBuffer> mCurrentBuffer;
-
- sp<GraphicBuffer> mBuffer;
-
std::vector<uint32_t> mTexNames;
};
@@ -530,6 +540,7 @@
} else {
mRE = renderEngineFactory->createRenderEngine();
}
+ mBuffer = allocateDefaultBuffer();
}
struct ColorSourceVariant {
@@ -566,18 +577,18 @@
struct BufferSourceVariant {
static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
RenderEngineTest* fixture) {
- sp<GraphicBuffer> buf = RenderEngineTest::allocateSourceBuffer(1, 1);
+ const auto buf = fixture->allocateSourceBuffer(1, 1);
uint32_t texName;
fixture->mRE->genTextures(1, &texName);
fixture->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
- for (int32_t j = 0; j < buf->getHeight(); j++) {
- uint8_t* iter = pixels + (buf->getStride() * j) * 4;
- for (int32_t i = 0; i < buf->getWidth(); i++) {
+ for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
+ uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
+ for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
iter[0] = uint8_t(r * 255);
iter[1] = uint8_t(g * 255);
iter[2] = uint8_t(b * 255);
@@ -586,7 +597,7 @@
}
}
- buf->unlock();
+ buf->getBuffer()->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1012,14 +1023,14 @@
layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
// Here will allocate a checker board texture, but transform texture
// coordinates so that only the upper left is applied.
- sp<GraphicBuffer> buf = allocateSourceBuffer(2, 2);
+ const auto buf = allocateSourceBuffer(2, 2);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
// Red top left, Green top right, Blue bottom left, Black bottom right
pixels[0] = 255;
pixels[1] = 0;
@@ -1033,7 +1044,7 @@
pixels[9] = 0;
pixels[10] = 255;
pixels[11] = 255;
- buf->unlock();
+ buf->getBuffer()->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1061,19 +1072,19 @@
std::vector<const renderengine::LayerSettings*> layers;
renderengine::LayerSettings layer;
- sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
+ const auto buf = allocateSourceBuffer(1, 1);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
pixels[0] = 255;
pixels[1] = 0;
pixels[2] = 0;
pixels[3] = 255;
- buf->unlock();
+ buf->getBuffer()->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1100,19 +1111,19 @@
std::vector<const renderengine::LayerSettings*> layers;
renderengine::LayerSettings layer;
- sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
+ const auto buf = allocateSourceBuffer(1, 1);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
pixels[0] = 255;
pixels[1] = 0;
pixels[2] = 0;
pixels[3] = 255;
- buf->unlock();
+ buf->getBuffer()->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1233,8 +1244,7 @@
}
TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
- const auto& renderEngineFactory = GetParam();
- mRE = renderEngineFactory->createRenderEngine();
+ initializeRenderEngine();
renderengine::DisplaySettings settings;
settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
@@ -1295,7 +1305,6 @@
layers.push_back(&layer);
status_t status = mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), nullptr);
- mCurrentBuffer = mBuffer;
ASSERT_EQ(NO_ERROR, status);
expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
}
@@ -1323,9 +1332,8 @@
layers.push_back(&layer);
status_t status = mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd(), nullptr);
- mCurrentBuffer = mBuffer;
ASSERT_EQ(NO_ERROR, status);
- ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId()));
+ ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
}
@@ -1574,98 +1582,6 @@
clearRegion();
}
-TEST_P(RenderEngineTest, drawLayers_fillsBufferAndCachesImages) {
- const auto& renderEngineFactory = GetParam();
-
- if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
- // GLES-specific test
- return;
- }
-
- initializeRenderEngine();
-
- renderengine::DisplaySettings settings;
- settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
- settings.physicalDisplay = fullscreenRect();
- settings.clip = fullscreenRect();
-
- std::vector<const renderengine::LayerSettings*> layers;
-
- renderengine::LayerSettings layer;
- layer.geometry.boundaries = fullscreenRect().toFloatRect();
- BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
-
- layers.push_back(&layer);
- invokeDraw(settings, layers);
- uint64_t bufferId = layer.source.buffer.buffer->getId();
- EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId));
- std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
- mGLESRE->unbindExternalTextureBufferForTesting(bufferId);
- std::lock_guard<std::mutex> lock(barrier->mutex);
- ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
- [&]() REQUIRES(barrier->mutex) {
- return barrier->isOpen;
- }));
- EXPECT_FALSE(mGLESRE->isImageCachedForTesting(bufferId));
- EXPECT_EQ(NO_ERROR, barrier->result);
-}
-
-TEST_P(RenderEngineTest, cacheExternalBuffer_withNullBuffer) {
- const auto& renderEngineFactory = GetParam();
-
- if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
- // GLES-specific test
- return;
- }
-
- initializeRenderEngine();
-
- std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
- mGLESRE->cacheExternalTextureBufferForTesting(nullptr);
- std::lock_guard<std::mutex> lock(barrier->mutex);
- ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
- [&]() REQUIRES(barrier->mutex) {
- return barrier->isOpen;
- }));
- EXPECT_TRUE(barrier->isOpen);
- EXPECT_EQ(BAD_VALUE, barrier->result);
-}
-
-TEST_P(RenderEngineTest, cacheExternalBuffer_cachesImages) {
- const auto& renderEngineFactory = GetParam();
-
- if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
- // GLES-specific test
- return;
- }
-
- initializeRenderEngine();
-
- sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
- uint64_t bufferId = buf->getId();
- std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
- mGLESRE->cacheExternalTextureBufferForTesting(buf);
- {
- std::lock_guard<std::mutex> lock(barrier->mutex);
- ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
- [&]() REQUIRES(barrier->mutex) {
- return barrier->isOpen;
- }));
- EXPECT_EQ(NO_ERROR, barrier->result);
- }
- EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId));
- barrier = mGLESRE->unbindExternalTextureBufferForTesting(bufferId);
- {
- std::lock_guard<std::mutex> lock(barrier->mutex);
- ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
- [&]() REQUIRES(barrier->mutex) {
- return barrier->isOpen;
- }));
- EXPECT_EQ(NO_ERROR, barrier->result);
- }
- EXPECT_FALSE(mGLESRE->isImageCachedForTesting(bufferId));
-}
-
TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
initializeRenderEngine();
@@ -1858,7 +1774,7 @@
sync_wait(fd, -1);
}
- uint64_t bufferId = layer.source.buffer.buffer->getId();
+ uint64_t bufferId = layer.source.buffer.buffer->getBuffer()->getId();
uint32_t texName = layer.source.buffer.textureName;
EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId));
EXPECT_EQ(bufferId, mGLESRE->getBufferIdForTextureNameForTesting(texName));
@@ -1966,16 +1882,16 @@
// The next layer will overwrite redLayer with a GraphicBuffer that is green
// applied with a translucent alpha.
- auto buf = allocateSourceBuffer(1, 1);
+ const auto buf = allocateSourceBuffer(1, 1);
{
uint8_t* pixels;
- buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
pixels[0] = 0;
pixels[1] = 255;
pixels[2] = 0;
pixels[3] = 255;
- buf->unlock();
+ buf->getBuffer()->unlock();
}
const renderengine::LayerSettings greenLayer{
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index b093e88..e3917cc 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -162,15 +162,18 @@
TEST_F(RenderEngineThreadedTest, drawLayers) {
renderengine::DisplaySettings settings;
std::vector<const renderengine::LayerSettings*> layers;
- sp<GraphicBuffer> buffer = new GraphicBuffer();
+ std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), *mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
base::unique_fd bufferFence;
base::unique_fd drawFence;
EXPECT_CALL(*mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings&,
const std::vector<const renderengine::LayerSettings*>&,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> status_t { return NO_ERROR; });
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd&&, base::unique_fd*) -> status_t { return NO_ERROR; });
status_t result = mThreadedRE->drawLayers(settings, layers, buffer, false,
std::move(bufferFence), &drawFence);
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index 194c7da..c9f6296 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -157,27 +157,28 @@
resultFuture.wait();
}
-void RenderEngineThreaded::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
+ bool isRenderable) {
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::cacheExternalTextureBuffer");
- instance.cacheExternalTextureBuffer(buffer);
+ ATRACE_NAME("REThreaded::mapExternalTextureBuffer");
+ instance.mapExternalTextureBuffer(buffer, isRenderable);
});
}
mCondition.notify_one();
}
-void RenderEngineThreaded::unbindExternalTextureBuffer(uint64_t bufferId) {
+void RenderEngineThreaded::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::unbindExternalTextureBuffer");
- instance.unbindExternalTextureBuffer(bufferId);
+ ATRACE_NAME("REThreaded::unmapExternalTextureBuffer");
+ instance.unmapExternalTextureBuffer(buffer);
});
}
mCondition.notify_one();
@@ -239,7 +240,7 @@
status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const sp<GraphicBuffer>& buffer,
+ const std::shared_ptr<ExternalTexture>& buffer,
const bool useFramebufferCache,
base::unique_fd&& bufferFence,
base::unique_fd* drawFence) {
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index 61ae9b8..eb6098e 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -48,8 +48,6 @@
void genTextures(size_t count, uint32_t* names) override;
void deleteTextures(size_t count, uint32_t const* names) override;
- void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
- void unbindExternalTextureBuffer(uint64_t bufferId) override;
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
@@ -60,14 +58,19 @@
status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
- base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache, base::unique_fd&& bufferFence,
+ base::unique_fd* drawFence) override;
void cleanFramebufferCache() override;
int getContextPriority() override;
bool supportsBackgroundBlur() override;
void onPrimaryDisplaySizeChanged(ui::Size size) override;
+protected:
+ void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
+ void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
+
private:
void threadMain(CreateInstanceFactory factory);
void waitUntilInitialized() const;
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index be9bce0..13ac7c3 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -188,7 +188,7 @@
const bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) ||
(isSecure() && !targetSettings.isSecure);
const bool bufferCanBeUsedAsHwTexture =
- mBufferInfo.mBuffer->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
+ mBufferInfo.mBuffer->getBuffer()->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
compositionengine::LayerFE::LayerSettings& layer = *result;
if (blackOutLayer || !bufferCanBeUsedAsHwTexture) {
ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable",
@@ -213,7 +213,7 @@
? mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel
: defaultMaxContentLuminance;
layer.frameNumber = mCurrentFrameNumber;
- layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getId() : 0;
+ layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer()->getId() : 0;
const bool useFiltering =
targetSettings.needsFiltering || mNeedsFiltering || bufferNeedsFiltering();
@@ -314,7 +314,7 @@
: Hwc2::IComposerClient::Composition::DEVICE;
}
- compositionState->buffer = mBufferInfo.mBuffer;
+ compositionState->buffer = mBufferInfo.mBuffer->getBuffer();
compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
? 0
: mBufferInfo.mBufferSlot;
@@ -442,7 +442,7 @@
void BufferLayer::gatherBufferInfo() {
mBufferInfo.mPixelFormat =
- !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->format;
+ !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->getBuffer()->format;
mBufferInfo.mFrameLatencyNeeded = true;
}
@@ -544,10 +544,10 @@
}
if (oldBufferInfo.mBuffer != nullptr) {
- uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
- uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
- if (bufWidth != uint32_t(oldBufferInfo.mBuffer->width) ||
- bufHeight != uint32_t(oldBufferInfo.mBuffer->height)) {
+ uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
+ if (bufWidth != uint32_t(oldBufferInfo.mBuffer->getBuffer()->width) ||
+ bufHeight != uint32_t(oldBufferInfo.mBuffer->getBuffer()->height)) {
recomputeVisibleRegions = true;
}
}
@@ -612,8 +612,8 @@
}
bool BufferLayer::isProtected() const {
- const sp<GraphicBuffer>& buffer(mBufferInfo.mBuffer);
- return (buffer != 0) && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+ return (mBufferInfo.mBuffer != nullptr) &&
+ (mBufferInfo.mBuffer->getBuffer()->getUsage() & GRALLOC_USAGE_PROTECTED);
}
// h/w composer set-up
@@ -727,8 +727,8 @@
return Rect::INVALID_RECT;
}
- uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
- uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
+ uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
// Undo any transformations on the buffer and return the result.
if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
@@ -759,8 +759,8 @@
return parentBounds;
}
- uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
- uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
+ uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
// Undo any transformations on the buffer and return the result.
if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
@@ -802,7 +802,7 @@
return mBufferInfo.mCrop;
} else if (mBufferInfo.mBuffer != nullptr) {
// otherwise we use the whole buffer
- return mBufferInfo.mBuffer->getBounds();
+ return mBufferInfo.mBuffer->getBuffer()->getBounds();
} else {
// if we don't have a buffer yet, we use an empty/invalid crop
return Rect();
@@ -847,12 +847,14 @@
}
sp<GraphicBuffer> BufferLayer::getBuffer() const {
- return mBufferInfo.mBuffer;
+ return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr;
}
void BufferLayer::getDrawingTransformMatrix(bool filteringEnabled, float outMatrix[16]) {
- GLConsumer::computeTransformMatrix(outMatrix, mBufferInfo.mBuffer, mBufferInfo.mCrop,
- mBufferInfo.mTransform, filteringEnabled);
+ GLConsumer::computeTransformMatrix(outMatrix,
+ mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer()
+ : nullptr,
+ mBufferInfo.mCrop, mBufferInfo.mTransform, filteringEnabled);
}
void BufferLayer::setInitialValuesForClone(const sp<Layer>& clonedFrom) {
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index b8d3f12..8553247 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -134,7 +134,7 @@
PixelFormat mPixelFormat{PIXEL_FORMAT_NONE};
bool mTransformToDisplayInverse{false};
- sp<GraphicBuffer> mBuffer;
+ std::shared_ptr<renderengine::ExternalTexture> mBuffer;
int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
bool mFrameLatencyNeeded{false};
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 69d2d11..96b2247 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -40,7 +40,6 @@
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
-#include <renderengine/Image.h>
#include <renderengine/RenderEngine.h>
#include <utils/Log.h>
#include <utils/String8.h>
@@ -167,7 +166,7 @@
}
auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer
- : mCurrentTextureBuffer->graphicBuffer();
+ : mCurrentTextureBuffer->getBuffer();
auto err = addReleaseFence(slot, buffer, fence);
if (err != OK) {
BLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", strerror(-err), err);
@@ -206,9 +205,11 @@
// before, so we need to clean up old references.
if (item->mGraphicBuffer != nullptr) {
std::lock_guard<std::mutex> lock(mImagesMutex);
- if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->graphicBuffer() == nullptr ||
- mImages[item->mSlot]->graphicBuffer()->getId() != item->mGraphicBuffer->getId()) {
- mImages[item->mSlot] = std::make_shared<Image>(item->mGraphicBuffer, mRE);
+ if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->getBuffer() == nullptr ||
+ mImages[item->mSlot]->getBuffer()->getId() != item->mGraphicBuffer->getId()) {
+ mImages[item->mSlot] = std::make_shared<
+ renderengine::ExternalTexture>(item->mGraphicBuffer, mRE,
+ renderengine::ExternalTexture::Usage::READABLE);
}
}
@@ -222,8 +223,8 @@
int slot = item.mSlot;
BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture,
- (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->graphicBuffer() != nullptr)
- ? mCurrentTextureBuffer->graphicBuffer()->handle
+ (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->getBuffer() != nullptr)
+ ? mCurrentTextureBuffer->getBuffer()->handle
: 0,
slot, mSlots[slot].mGraphicBuffer->handle);
@@ -231,7 +232,7 @@
// releaseBufferLocked() if we're in shared buffer mode and both buffers are
// the same.
- std::shared_ptr<Image> nextTextureBuffer;
+ std::shared_ptr<renderengine::ExternalTexture> nextTextureBuffer;
{
std::lock_guard<std::mutex> lock(mImagesMutex);
nextTextureBuffer = mImages[slot];
@@ -241,7 +242,7 @@
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
if (pendingRelease == nullptr) {
status_t status =
- releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->graphicBuffer());
+ releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->getBuffer());
if (status < NO_ERROR) {
BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status),
status);
@@ -250,7 +251,7 @@
}
} else {
pendingRelease->currentTexture = mCurrentTexture;
- pendingRelease->graphicBuffer = mCurrentTextureBuffer->graphicBuffer();
+ pendingRelease->graphicBuffer = mCurrentTextureBuffer->getBuffer();
pendingRelease->isPending = true;
}
}
@@ -301,14 +302,14 @@
void BufferLayerConsumer::computeCurrentTransformMatrixLocked() {
BLC_LOGV("computeCurrentTransformMatrixLocked");
- if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->graphicBuffer() == nullptr) {
+ if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->getBuffer() == nullptr) {
BLC_LOGD("computeCurrentTransformMatrixLocked: "
"mCurrentTextureBuffer is nullptr");
}
GLConsumer::computeTransformMatrix(mCurrentTransformMatrix,
mCurrentTextureBuffer == nullptr
? nullptr
- : mCurrentTextureBuffer->graphicBuffer(),
+ : mCurrentTextureBuffer->getBuffer(),
getCurrentCropLocked(), mCurrentTransform,
mFilteringEnabled);
}
@@ -360,7 +361,8 @@
return mCurrentApi;
}
-sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot, sp<Fence>* outFence) const {
+std::shared_ptr<renderengine::ExternalTexture> BufferLayerConsumer::getCurrentBuffer(
+ int* outSlot, sp<Fence>* outFence) const {
Mutex::Autolock lock(mMutex);
if (outSlot != nullptr) {
@@ -371,7 +373,7 @@
*outFence = mCurrentFence;
}
- return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer->graphicBuffer();
+ return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer;
}
Rect BufferLayerConsumer::getCurrentCrop() const {
@@ -456,10 +458,12 @@
void BufferLayerConsumer::onBufferAvailable(const BufferItem& item) {
if (item.mGraphicBuffer != nullptr && item.mSlot != BufferQueue::INVALID_BUFFER_SLOT) {
std::lock_guard<std::mutex> lock(mImagesMutex);
- const std::shared_ptr<Image>& oldImage = mImages[item.mSlot];
- if (oldImage == nullptr || oldImage->graphicBuffer() == nullptr ||
- oldImage->graphicBuffer()->getId() != item.mGraphicBuffer->getId()) {
- mImages[item.mSlot] = std::make_shared<Image>(item.mGraphicBuffer, mRE);
+ const std::shared_ptr<renderengine::ExternalTexture>& oldImage = mImages[item.mSlot];
+ if (oldImage == nullptr || oldImage->getBuffer() == nullptr ||
+ oldImage->getBuffer()->getId() != item.mGraphicBuffer->getId()) {
+ mImages[item.mSlot] = std::make_shared<
+ renderengine::ExternalTexture>(item.mGraphicBuffer, mRE,
+ renderengine::ExternalTexture::Usage::READABLE);
}
}
}
@@ -499,22 +503,6 @@
ConsumerBase::dumpLocked(result, prefix);
}
-
-BufferLayerConsumer::Image::Image(const sp<GraphicBuffer>& graphicBuffer,
- renderengine::RenderEngine& engine)
- : mGraphicBuffer(graphicBuffer), mRE(engine) {
- if (graphicBuffer != nullptr && (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED)) {
- return;
- }
- mRE.cacheExternalTextureBuffer(mGraphicBuffer);
-}
-
-BufferLayerConsumer::Image::~Image() {
- if (mGraphicBuffer != nullptr) {
- ALOGV("Destroying buffer: %" PRId64, mGraphicBuffer->getId());
- mRE.unbindExternalTextureBuffer(mGraphicBuffer->getId());
- }
-}
}; // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index dd39214..9ed80b4 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -21,12 +21,11 @@
#include <gui/BufferQueueDefs.h>
#include <gui/ConsumerBase.h>
#include <gui/HdrMetadata.h>
-
+#include <renderengine/ExternalTexture.h>
#include <ui/FenceTime.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicTypes.h>
#include <ui/Region.h>
-
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/threads.h>
@@ -39,7 +38,6 @@
namespace renderengine {
class RenderEngine;
-class Image;
} // namespace renderengine
/*
@@ -153,7 +151,8 @@
// When outSlot is not nullptr, the current buffer slot index is also
// returned. Simiarly, when outFence is not nullptr, the current output
// fence is returned.
- sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr, sp<Fence>* outFence = nullptr) const;
+ std::shared_ptr<renderengine::ExternalTexture> getCurrentBuffer(
+ int* outSlot = nullptr, sp<Fence>* outFence = nullptr) const;
// getCurrentCrop returns the cropping rectangle of the current buffer.
Rect getCurrentCrop() const;
@@ -258,7 +257,7 @@
// mCurrentTextureBuffer is the buffer containing the current texture. It's
// possible that this buffer is not associated with any buffer slot, so we
// must track it separately in order to support the getCurrentBuffer method.
- std::shared_ptr<Image> mCurrentTextureBuffer;
+ std::shared_ptr<renderengine::ExternalTexture> mCurrentTextureBuffer;
// mCurrentCrop is the crop rectangle that applies to the current texture.
// It gets set each time updateTexImage is called.
@@ -337,7 +336,8 @@
int mCurrentTexture;
// Shadow buffer cache for cleaning up renderengine references.
- std::shared_ptr<Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex);
+ std::shared_ptr<renderengine::ExternalTexture>
+ mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex);
// Separate mutex guarding the shadow buffer cache.
// mImagesMutex can be manipulated with binder threads (e.g. onBuffersAllocated)
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index ed826a0..c533969 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -71,14 +71,8 @@
// original layer and the clone should be removed at the same time so there shouldn't be any
// issue with the clone layer trying to use the texture.
if (mBufferInfo.mBuffer != nullptr && !isClone()) {
- // Ensure that mBuffer is uncached from RenderEngine here, as
- // RenderEngine may have been using the buffer as an external texture
- // after the client uncached the buffer.
- auto& engine(mFlinger->getRenderEngine());
- const uint64_t bufferId = mBufferInfo.mBuffer->getId();
- engine.unbindExternalTextureBuffer(bufferId);
- callReleaseBufferCallback(mDrawingState.releaseBufferListener, mBufferInfo.mBuffer,
- mBufferInfo.mFence);
+ callReleaseBufferCallback(mDrawingState.releaseBufferListener,
+ mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFence);
}
}
@@ -363,8 +357,9 @@
return true;
}
-bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence,
- nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp,
+bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& buffer,
+ const sp<Fence>& acquireFence, nsecs_t postTime,
+ nsecs_t desiredPresentTime, bool isAutoTimestamp,
const client_cache_t& clientCacheId, uint64_t frameNumber,
std::optional<nsecs_t> dequeueTime, const FrameTimelineInfo& info,
const sp<ITransactionCompletedListener>& releaseBufferListener) {
@@ -372,12 +367,14 @@
if (mCurrentState.buffer) {
mReleasePreviousBuffer = true;
- if (mCurrentState.buffer != mDrawingState.buffer) {
+ if (!mDrawingState.buffer ||
+ mCurrentState.buffer->getBuffer() != mDrawingState.buffer->getBuffer()) {
// If mCurrentState has a buffer, and we are about to update again
// before swapping to drawing state, then the first buffer will be
// dropped and we should decrement the pending buffer count and
// call any release buffer callbacks if set.
- callReleaseBufferCallback(mCurrentState.releaseBufferListener, mCurrentState.buffer,
+ callReleaseBufferCallback(mCurrentState.releaseBufferListener,
+ mCurrentState.buffer->getBuffer(),
mCurrentState.acquireFence);
decrementPendingBufferCount();
if (mCurrentState.bufferSurfaceFrameTX != nullptr) {
@@ -415,8 +412,8 @@
setFrameTimelineVsyncForBufferTransaction(info, postTime);
- if (dequeueTime && *dequeueTime != 0) {
- const uint64_t bufferId = buffer->getId();
+ if (buffer && dequeueTime && *dequeueTime != 0) {
+ const uint64_t bufferId = buffer->getBuffer()->getId();
mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, *dequeueTime,
FrameTracer::FrameEvent::DEQUEUE);
@@ -424,8 +421,8 @@
FrameTracer::FrameEvent::QUEUE);
}
- mCurrentState.width = mCurrentState.buffer->width;
- mCurrentState.height = mCurrentState.buffer->height;
+ mCurrentState.width = mCurrentState.buffer->getBuffer()->getWidth();
+ mCurrentState.height = mCurrentState.buffer->getBuffer()->getHeight();
return true;
}
@@ -674,7 +671,7 @@
}
const int32_t layerId = getSequence();
- const uint64_t bufferId = mDrawingState.buffer->getId();
+ const uint64_t bufferId = mDrawingState.buffer->getBuffer()->getId();
const uint64_t frameNumber = mDrawingState.frameNumber;
const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence);
mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
@@ -708,7 +705,7 @@
return BAD_VALUE;
}
- if (s.buffer != mBufferInfo.mBuffer) {
+ if (!mBufferInfo.mBuffer || s.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) {
decrementPendingBufferCount();
}
@@ -827,13 +824,13 @@
Rect BufferStateLayer::computeCrop(const State& s) {
if (s.crop.isEmpty() && s.buffer) {
- return s.buffer->getBounds();
+ return s.buffer->getBuffer()->getBounds();
} else if (s.buffer) {
Rect crop = s.crop;
crop.left = std::max(crop.left, 0);
crop.top = std::max(crop.top, 0);
- uint32_t bufferWidth = s.buffer->getWidth();
- uint32_t bufferHeight = s.buffer->getHeight();
+ uint32_t bufferWidth = s.buffer->getBuffer()->getWidth();
+ uint32_t bufferHeight = s.buffer->getBuffer()->getHeight();
if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
bufferWidth <= std::numeric_limits<int32_t>::max()) {
crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
@@ -841,7 +838,7 @@
}
if (!crop.isValid()) {
// Crop rect is out of bounds, return whole buffer
- return s.buffer->getBounds();
+ return s.buffer->getBuffer()->getBounds();
}
return crop;
}
@@ -863,8 +860,8 @@
return false;
}
- uint32_t bufferWidth = s.buffer->width;
- uint32_t bufferHeight = s.buffer->height;
+ uint32_t bufferWidth = s.buffer->getBuffer()->width;
+ uint32_t bufferHeight = s.buffer->getBuffer()->height;
// Undo any transformations on the buffer and return the result.
if (s.bufferTransform & ui::Transform::ROT_90) {
@@ -891,14 +888,16 @@
ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
}
-void BufferStateLayer::bufferMayChange(sp<GraphicBuffer>& newBuffer) {
- if (mDrawingState.buffer != nullptr && mDrawingState.buffer != mBufferInfo.mBuffer &&
- newBuffer != mDrawingState.buffer) {
+void BufferStateLayer::bufferMayChange(const sp<GraphicBuffer>& newBuffer) {
+ if (mDrawingState.buffer != nullptr &&
+ (!mBufferInfo.mBuffer ||
+ mDrawingState.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) &&
+ newBuffer != mDrawingState.buffer->getBuffer()) {
// If we are about to update mDrawingState.buffer but it has not yet latched
// then we will drop a buffer and should decrement the pending buffer count and
// call any release buffer callbacks if set.
- callReleaseBufferCallback(mDrawingState.releaseBufferListener, mDrawingState.buffer,
- mDrawingState.acquireFence);
+ callReleaseBufferCallback(mDrawingState.releaseBufferListener,
+ mDrawingState.buffer->getBuffer(), mDrawingState.acquireFence);
decrementPendingBufferCount();
}
}
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 8ce3e1f..a69d07f 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -66,9 +66,9 @@
bool setTransform(uint32_t transform) override;
bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
bool setCrop(const Rect& crop) override;
- bool setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence, nsecs_t postTime,
- nsecs_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t& clientCacheId, uint64_t frameNumber,
+ bool setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& buffer,
+ const sp<Fence>& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime,
+ bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber,
std::optional<nsecs_t> dequeueTime, const FrameTimelineInfo& info,
const sp<ITransactionCompletedListener>& transactionListener) override;
bool setAcquireFence(const sp<Fence>& fence) override;
@@ -108,7 +108,7 @@
// See mPendingBufferTransactions
void decrementPendingBufferCount();
- void bufferMayChange(sp<GraphicBuffer>& newBuffer) override;
+ void bufferMayChange(const sp<GraphicBuffer>& newBuffer) override;
std::atomic<int32_t>* getPendingBufferCounter() override { return &mPendingBufferTransactions; }
std::string getPendingBufferCounterName() override { return mBlastTransactionName; }
diff --git a/services/surfaceflinger/ClientCache.cpp b/services/surfaceflinger/ClientCache.cpp
index 44b33ef..f310738 100644
--- a/services/surfaceflinger/ClientCache.cpp
+++ b/services/surfaceflinger/ClientCache.cpp
@@ -102,7 +102,12 @@
return false;
}
- processBuffers[id].buffer = buffer;
+ LOG_ALWAYS_FATAL_IF(mRenderEngine == nullptr,
+ "Attempted to build the ClientCache before a RenderEngine instance was "
+ "ready!");
+ processBuffers[id].buffer = std::make_shared<
+ renderengine::ExternalTexture>(buffer, *mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE);
return true;
}
@@ -132,7 +137,7 @@
}
}
-sp<GraphicBuffer> ClientCache::get(const client_cache_t& cacheId) {
+std::shared_ptr<renderengine::ExternalTexture> ClientCache::get(const client_cache_t& cacheId) {
std::lock_guard lock(mMutex);
ClientCacheBuffer* buf = nullptr;
@@ -213,8 +218,8 @@
auto &buffers = i.second.second;
for (auto& [id, clientCacheBuffer] : buffers) {
StringAppendF(&result, "\t ID: %d, Width/Height: %d,%d\n", (int)id,
- (int)clientCacheBuffer.buffer->getWidth(),
- (int)clientCacheBuffer.buffer->getHeight());
+ (int)clientCacheBuffer.buffer->getBuffer()->getWidth(),
+ (int)clientCacheBuffer.buffer->getBuffer()->getHeight());
}
}
}
diff --git a/services/surfaceflinger/ClientCache.h b/services/surfaceflinger/ClientCache.h
index 0d597c8..a9b8177 100644
--- a/services/surfaceflinger/ClientCache.h
+++ b/services/surfaceflinger/ClientCache.h
@@ -19,6 +19,7 @@
#include <android-base/thread_annotations.h>
#include <binder/IBinder.h>
#include <gui/LayerState.h>
+#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
@@ -39,7 +40,11 @@
bool add(const client_cache_t& cacheId, const sp<GraphicBuffer>& buffer);
void erase(const client_cache_t& cacheId);
- sp<GraphicBuffer> get(const client_cache_t& cacheId);
+ std::shared_ptr<renderengine::ExternalTexture> get(const client_cache_t& cacheId);
+
+ // Always called immediately after setup. Will be set to non-null, and then should never be
+ // called again.
+ void setRenderEngine(renderengine::RenderEngine* renderEngine) { mRenderEngine = renderEngine; }
void removeProcess(const wp<IBinder>& processToken);
@@ -59,7 +64,7 @@
std::mutex mMutex;
struct ClientCacheBuffer {
- sp<GraphicBuffer> buffer;
+ std::shared_ptr<renderengine::ExternalTexture> buffer;
std::set<wp<ErasedRecipient>> recipients;
};
std::map<wp<IBinder> /*caching process*/,
@@ -73,6 +78,7 @@
};
sp<CacheDeathRecipient> mDeathRecipient;
+ renderengine::RenderEngine* mRenderEngine = nullptr;
bool getBuffer(const client_cache_t& cacheId, ClientCacheBuffer** outClientCacheBuffer)
REQUIRES(mMutex);
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index f680460..daee83b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -16,15 +16,16 @@
#pragma once
-#include <cstdint>
-#include <vector>
-
+#include <renderengine/ExternalTexture.h>
#include <ui/Fence.h>
#include <ui/GraphicTypes.h>
#include <ui/Size.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
+#include <cstdint>
+#include <vector>
+
namespace android {
class GraphicBuffer;
@@ -80,7 +81,8 @@
virtual void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) = 0;
// Allocates a buffer as scratch space for GPU composition
- virtual sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) = 0;
+ virtual std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer(
+ base::unique_fd* bufferFence) = 0;
// Queues the drawn buffer for consumption by HWC. readyFence is the fence
// which will fire when the buffer is ready for consumption.
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
index a1230b3..a8d372c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
@@ -45,6 +45,8 @@
// The DisplaySurface for this surface
sp<DisplaySurface> displaySurface;
+
+ size_t maxTextureCacheSize;
};
/**
@@ -81,6 +83,11 @@
return *this;
}
+ RenderSurfaceCreationArgsBuilder& setMaxTextureCacheSize(size_t maxTextureCacheSize) {
+ mArgs.maxTextureCacheSize = maxTextureCacheSize;
+ return *this;
+ }
+
private:
RenderSurfaceCreationArgs mArgs;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 48a54d6..c61ec59 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -18,7 +18,7 @@
#include <compositionengine/ProjectionSpace.h>
#include <compositionengine/impl/HwcBufferCache.h>
-#include <renderengine/Mesh.h>
+#include <renderengine/ExternalTexture.h>
#include <ui/FloatRect.h>
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
@@ -89,7 +89,7 @@
// Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState
struct {
- sp<GraphicBuffer> buffer = nullptr;
+ std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
sp<Fence> acquireFence = nullptr;
Rect displayFrame = {};
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index 5127a6f..a8a5380 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -16,12 +16,16 @@
#pragma once
-#include <memory>
-
#include <android-base/unique_fd.h>
#include <compositionengine/RenderSurface.h>
#include <utils/StrongPointer.h>
+#include <memory>
+#include <vector>
+
+#include "renderengine/ExternalTexture.h"
+#include "renderengine/RenderEngine.h"
+
struct ANativeWindow;
namespace android {
@@ -54,7 +58,8 @@
void setProtected(bool useProtected) override;
status_t beginFrame(bool mustRecompose) override;
void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) override;
- sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) override;
+ std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer(
+ base::unique_fd* bufferFence) override;
void queueBuffer(base::unique_fd readyFence) override;
void onPresentDisplayCompleted() override;
void flip() override;
@@ -66,7 +71,7 @@
// Testing
void setPageFlipCountForTest(std::uint32_t);
void setSizeForTest(const ui::Size&);
- sp<GraphicBuffer>& mutableGraphicBufferForTest();
+ std::shared_ptr<renderengine::ExternalTexture>& mutableTextureForTest();
base::unique_fd& mutableBufferReadyForTest();
private:
@@ -75,10 +80,13 @@
// ANativeWindow being rendered into
const sp<ANativeWindow> mNativeWindow;
- // Current buffer being rendered into
- sp<GraphicBuffer> mGraphicBuffer;
+
+ std::vector<std::shared_ptr<renderengine::ExternalTexture>> mTextureCache;
+ // Current texture being rendered into
+ std::shared_ptr<renderengine::ExternalTexture> mTexture;
const sp<DisplaySurface> mDisplaySurface;
ui::Size mSize;
+ const size_t mMaxTextureCacheSize;
bool mProtected{false};
std::uint32_t mPageFlipCount{0};
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
index c5d03a7..53f4a30 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
@@ -66,7 +66,7 @@
const Rect& getBounds() const { return mBounds; }
const Region& getVisibleRegion() const { return mVisibleRegion; }
size_t getAge() const { return mAge; }
- const sp<GraphicBuffer>& getBuffer() const { return mTexture.getBuffer(); }
+ const std::shared_ptr<renderengine::ExternalTexture>& getBuffer() const { return mTexture; }
const sp<Fence>& getDrawFence() const { return mDrawFence; }
const ProjectionSpace& getOutputSpace() const { return mOutputSpace; }
ui::Dataspace getOutputDataspace() const { return mOutputDataspace; }
@@ -87,7 +87,7 @@
void setLastUpdate(std::chrono::steady_clock::time_point now) { mLastUpdate = now; }
void append(const CachedSet& other) {
- mTexture.setBuffer(nullptr, nullptr);
+ mTexture = nullptr;
mOutputDataspace = ui::Dataspace::UNKNOWN;
mDrawFence = nullptr;
@@ -115,31 +115,7 @@
Region mVisibleRegion;
size_t mAge = 0;
- class Texture {
- public:
- ~Texture() { setBuffer(nullptr, nullptr); }
-
- void setBuffer(const sp<GraphicBuffer>& buffer, renderengine::RenderEngine* re) {
- if (mRE && mBuffer) {
- mRE->unbindExternalTextureBuffer(mBuffer->getId());
- }
-
- mBuffer = buffer;
- mRE = re;
-
- if (mRE && mBuffer) {
- mRE->cacheExternalTextureBuffer(mBuffer);
- }
- }
-
- const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
-
- private:
- sp<GraphicBuffer> mBuffer = nullptr;
- renderengine::RenderEngine* mRE = nullptr;
- };
-
- Texture mTexture;
+ std::shared_ptr<renderengine::ExternalTexture> mTexture;
sp<Fence> mDrawFence;
ProjectionSpace mOutputSpace;
ui::Dataspace mOutputDataspace;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index a0cae6f..fe858c2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -39,7 +39,7 @@
MOCK_METHOD1(setBufferPixelFormat, void(ui::PixelFormat));
MOCK_METHOD1(beginFrame, status_t(bool mustRecompose));
MOCK_METHOD2(prepareFrame, void(bool, bool));
- MOCK_METHOD1(dequeueBuffer, sp<GraphicBuffer>(base::unique_fd*));
+ MOCK_METHOD1(dequeueBuffer, std::shared_ptr<renderengine::ExternalTexture>(base::unique_fd*));
MOCK_METHOD1(queueBuffer, void(base::unique_fd));
MOCK_METHOD0(onPresentDisplayCompleted, void());
MOCK_METHOD0(flip, void());
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 3ac5433..3468b20 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#include <thread>
-
+#include <SurfaceFlingerProperties.sysprop.h>
#include <android-base/stringprintf.h>
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/CompositionRefreshArgs.h>
@@ -29,7 +28,9 @@
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <compositionengine/impl/planner/Planner.h>
-#include <SurfaceFlingerProperties.sysprop.h>
+#include <thread>
+
+#include "renderengine/ExternalTexture.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
@@ -715,11 +716,11 @@
bool skipLayer = false;
if (layer->getState().overrideInfo.buffer != nullptr) {
if (previousOverride != nullptr &&
- layer->getState().overrideInfo.buffer == previousOverride) {
+ layer->getState().overrideInfo.buffer->getBuffer() == previousOverride) {
ALOGV("Skipping redundant buffer");
skipLayer = true;
}
- previousOverride = layer->getState().overrideInfo.buffer;
+ previousOverride = layer->getState().overrideInfo.buffer->getBuffer();
}
const bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
@@ -978,14 +979,15 @@
}
base::unique_fd fd;
- sp<GraphicBuffer> buf;
+
+ std::shared_ptr<renderengine::ExternalTexture> tex;
// If we aren't doing client composition on this output, but do have a
// flipClientTarget request for this frame on this output, we still need to
// dequeue a buffer.
if (hasClientComposition || outputState.flipClientTarget) {
- buf = mRenderSurface->dequeueBuffer(&fd);
- if (buf == nullptr) {
+ tex = mRenderSurface->dequeueBuffer(&fd);
+ if (tex == nullptr) {
ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
"client composition for this frame",
mName.c_str());
@@ -1030,13 +1032,14 @@
// Check if the client composition requests were rendered into the provided graphic buffer. If
// so, we can reuse the buffer and avoid client composition.
if (mClientCompositionRequestCache) {
- if (mClientCompositionRequestCache->exists(buf->getId(), clientCompositionDisplay,
+ if (mClientCompositionRequestCache->exists(tex->getBuffer()->getId(),
+ clientCompositionDisplay,
clientCompositionLayers)) {
outputCompositionState.reusedClientComposition = true;
setExpensiveRenderingExpected(false);
return readyFence;
}
- mClientCompositionRequestCache->add(buf->getId(), clientCompositionDisplay,
+ mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay,
clientCompositionLayers);
}
@@ -1069,12 +1072,12 @@
// over to RenderEngine, in which case this flag can be removed from the drawLayers interface.
const bool useFramebufferCache = outputState.layerStackInternal;
status_t status =
- renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buf,
+ renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, tex,
useFramebufferCache, std::move(fd), &readyFence);
if (status != NO_ERROR && mClientCompositionRequestCache) {
// If rendering was not successful, remove the request from the cache.
- mClientCompositionRequestCache->remove(buf->getId());
+ mClientCompositionRequestCache->remove(tex->getBuffer()->getId());
}
auto& timeStats = getCompositionEngine().getTimeStats();
@@ -1151,9 +1154,9 @@
std::vector<LayerFE::LayerSettings> results;
if (layer->getState().overrideInfo.buffer != nullptr) {
- if (layer->getState().overrideInfo.buffer != previousOverrideBuffer) {
+ if (layer->getState().overrideInfo.buffer->getBuffer() != previousOverrideBuffer) {
results = layer->getOverrideCompositionList();
- previousOverrideBuffer = layer->getState().overrideInfo.buffer;
+ previousOverrideBuffer = layer->getState().overrideInfo.buffer->getBuffer();
ALOGV("Replacing [%s] with override in RE", layer->getLayerFE().getDebugName());
} else {
ALOGV("Skipping redundant override buffer for [%s] in RE",
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index f640f85..9ca8914 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -537,7 +537,7 @@
sp<GraphicBuffer> buffer = outputIndependentState.buffer;
sp<Fence> acquireFence = outputIndependentState.acquireFence;
if (getState().overrideInfo.buffer != nullptr) {
- buffer = getState().overrideInfo.buffer;
+ buffer = getState().overrideInfo.buffer->getBuffer();
acquireFence = getState().overrideInfo.acquireFence;
}
@@ -699,7 +699,7 @@
settings.geometry = renderengine::Geometry{
.boundaries = boundaries.toFloatRect(),
};
- settings.bufferId = getState().overrideInfo.buffer->getId();
+ settings.bufferId = getState().overrideInfo.buffer->getBuffer()->getId();
settings.source = renderengine::PixelSource{
.buffer = renderengine::Buffer{
.buffer = getState().overrideInfo.buffer,
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index 3bef77d..ef50870 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -25,8 +25,8 @@
#include <compositionengine/impl/DumpHelpers.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/RenderSurface.h>
-
#include <log/log.h>
+#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <system/window.h>
#include <ui/GraphicBuffer.h>
@@ -63,7 +63,8 @@
mDisplay(display),
mNativeWindow(args.nativeWindow),
mDisplaySurface(args.displaySurface),
- mSize(args.displayWidth, args.displayHeight) {
+ mSize(args.displayWidth, args.displayHeight),
+ mMaxTextureCacheSize(args.maxTextureCacheSize) {
LOG_ALWAYS_FATAL_IF(!mNativeWindow);
}
@@ -146,7 +147,8 @@
}
}
-sp<GraphicBuffer> RenderSurface::dequeueBuffer(base::unique_fd* bufferFence) {
+std::shared_ptr<renderengine::ExternalTexture> RenderSurface::dequeueBuffer(
+ base::unique_fd* bufferFence) {
ATRACE_CALL();
int fd = -1;
ANativeWindowBuffer* buffer = nullptr;
@@ -158,16 +160,41 @@
mDisplay.getName().c_str(), result);
// Return fast here as we can't do much more - any rendering we do
// now will just be wrong.
- return mGraphicBuffer;
+ return mTexture;
}
- ALOGW_IF(mGraphicBuffer != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
- mGraphicBuffer->getNativeBuffer()->handle);
- mGraphicBuffer = GraphicBuffer::from(buffer);
+ ALOGW_IF(mTexture != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
+ mTexture->getBuffer()->getNativeBuffer()->handle);
+
+ sp<GraphicBuffer> newBuffer = GraphicBuffer::from(buffer);
+
+ std::shared_ptr<renderengine::ExternalTexture> texture;
+
+ for (auto it = mTextureCache.begin(); it != mTextureCache.end(); it++) {
+ const auto& cachedTexture = *it;
+ if (cachedTexture->getBuffer()->getId() == newBuffer->getId()) {
+ texture = cachedTexture;
+ mTextureCache.erase(it);
+ break;
+ }
+ }
+
+ if (texture) {
+ mTexture = texture;
+ } else {
+ mTexture = std::make_shared<
+ renderengine::ExternalTexture>(GraphicBuffer::from(buffer),
+ mCompositionEngine.getRenderEngine(),
+ renderengine::ExternalTexture::Usage::WRITEABLE);
+ }
+ mTextureCache.push_back(mTexture);
+ if (mTextureCache.size() > mMaxTextureCacheSize) {
+ mTextureCache.erase(mTextureCache.begin());
+ }
*bufferFence = base::unique_fd(fd);
- return mGraphicBuffer;
+ return mTexture;
}
void RenderSurface::queueBuffer(base::unique_fd readyFence) {
@@ -177,24 +204,24 @@
// hasFlipClientTargetRequest could return true even if we haven't
// dequeued a buffer before. Try dequeueing one if we don't have a
// buffer ready.
- if (mGraphicBuffer == nullptr) {
+ if (mTexture == nullptr) {
ALOGI("Attempting to queue a client composited buffer without one "
"previously dequeued for display [%s]. Attempting to dequeue "
"a scratch buffer now",
mDisplay.getName().c_str());
- // We shouldn't deadlock here, since mGraphicBuffer == nullptr only
+ // We shouldn't deadlock here, since mTexture == nullptr only
// after a successful call to queueBuffer, or if dequeueBuffer has
// never been called.
base::unique_fd unused;
dequeueBuffer(&unused);
}
- if (mGraphicBuffer == nullptr) {
+ if (mTexture == nullptr) {
ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str());
} else {
- status_t result =
- mNativeWindow->queueBuffer(mNativeWindow.get(),
- mGraphicBuffer->getNativeBuffer(), dup(readyFence));
+ status_t result = mNativeWindow->queueBuffer(mNativeWindow.get(),
+ mTexture->getBuffer()->getNativeBuffer(),
+ dup(readyFence));
if (result != NO_ERROR) {
ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(),
result);
@@ -204,11 +231,12 @@
LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result);
} else {
mNativeWindow->cancelBuffer(mNativeWindow.get(),
- mGraphicBuffer->getNativeBuffer(), dup(readyFence));
+ mTexture->getBuffer()->getNativeBuffer(),
+ dup(readyFence));
}
}
- mGraphicBuffer = nullptr;
+ mTexture = nullptr;
}
}
@@ -256,8 +284,8 @@
mSize = size;
}
-sp<GraphicBuffer>& RenderSurface::mutableGraphicBufferForTest() {
- return mGraphicBuffer;
+std::shared_ptr<renderengine::ExternalTexture>& RenderSurface::mutableTextureForTest() {
+ return mTexture;
}
} // namespace impl
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index dcb7555..53557bb 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -130,7 +130,7 @@
}
bool CachedSet::hasReadyBuffer() const {
- return mTexture.getBuffer() != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled;
+ return mTexture != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled;
}
std::vector<CachedSet> CachedSet::decompose() const {
@@ -217,21 +217,27 @@
sp<GraphicBuffer> buffer = new GraphicBuffer(static_cast<uint32_t>(mBounds.getWidth()),
static_cast<uint32_t>(mBounds.getHeight()),
HAL_PIXEL_FORMAT_RGBA_8888, 1, usageFlags);
+ const auto texture = std::make_shared<
+ renderengine::ExternalTexture>(buffer, renderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
LOG_ALWAYS_FATAL_IF(buffer->initCheck() != OK);
base::unique_fd drawFence;
- status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, buffer, false,
- base::unique_fd(), &drawFence);
+ status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, mTexture,
+ false, base::unique_fd(), &drawFence);
if (result == NO_ERROR) {
- mTexture.setBuffer(buffer, &renderEngine);
mDrawFence = new Fence(drawFence.release());
mOutputSpace = ProjectionSpace(ui::Size(outputState.framebufferSpace.bounds.getWidth(),
outputState.framebufferSpace.bounds.getHeight()),
mBounds);
+ mTexture = std::move(texture);
mOutputSpace.orientation = outputState.framebufferSpace.orientation;
mOutputDataspace = outputDataspace;
mOrientation = orientation;
+ } else {
+ mTexture = nullptr;
}
}
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index ad75557..3a2534b 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -111,7 +111,12 @@
const GraphicBuffer* currentOverrideBuffer = nullptr;
bool hasSkippedLayers = false;
for (auto layer : layers) {
- const GraphicBuffer* overrideBuffer = layer->getState().overrideInfo.buffer.get();
+ if (!layer->getState().overrideInfo.buffer) {
+ continue;
+ }
+
+ const GraphicBuffer* overrideBuffer =
+ layer->getState().overrideInfo.buffer->getBuffer().get();
if (overrideBuffer != nullptr && overrideBuffer == currentOverrideBuffer) {
// Skip this layer since it is part of a previous cached set
hasSkippedLayers = true;
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 8a4d161..4c3f494 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -26,6 +26,7 @@
#include "MockHWC2.h"
#include "MockHWComposer.h"
#include "RegionMatcher.h"
+#include "renderengine/mock/RenderEngine.h"
namespace android::compositionengine {
namespace {
@@ -715,7 +716,7 @@
static const HdrMetadata kHdrMetadata;
static native_handle_t* kSidebandStreamHandle;
static const sp<GraphicBuffer> kBuffer;
- static const sp<GraphicBuffer> kOverrideBuffer;
+ std::shared_ptr<renderengine::ExternalTexture> kOverrideBuffer;
static const sp<Fence> kFence;
static const sp<Fence> kOverrideFence;
static const std::string kLayerGenericMetadata1Key;
@@ -724,6 +725,11 @@
static const std::vector<uint8_t> kLayerGenericMetadata2Value;
OutputLayerWriteStateToHWCTest() {
+ kOverrideBuffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::
+ WRITEABLE);
auto& outputLayerState = mOutputLayer.editState();
outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
@@ -839,6 +845,7 @@
std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
+ renderengine::mock::RenderEngine mRenderEngine;
};
const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
@@ -858,7 +865,6 @@
native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle =
reinterpret_cast<native_handle_t*>(1031);
const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
-const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kOverrideBuffer = new GraphicBuffer();
const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
const sp<Fence> OutputLayerWriteStateToHWCTest::kOverrideFence = new Fence();
const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Key =
@@ -1023,7 +1029,7 @@
kOverrideBufferTransform, kOverrideBlendMode, kOverrideAlpha);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
kOverrideSurfaceDamage);
- expectSetHdrMetadataAndBufferCalls(kOverrideBuffer, kOverrideFence);
+ expectSetHdrMetadataAndBufferCalls(kOverrideBuffer->getBuffer(), kOverrideFence);
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false);
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 5f0b0ee..e80100c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include <cmath>
-
#include <android-base/stringprintf.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/impl/Output.h>
@@ -31,9 +29,12 @@
#include <ui/Rect.h>
#include <ui/Region.h>
+#include <cmath>
+
#include "CallOrderStateMachineHelper.h"
#include "MockHWC2.h"
#include "RegionMatcher.h"
+#include "renderengine/ExternalTexture.h"
namespace android::compositionengine {
namespace {
@@ -2960,7 +2961,10 @@
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
StrictMock<OutputPartialMock> mOutput;
- sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
+ std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
std::optional<base::unique_fd> mReadyFence;
};
@@ -3173,7 +3177,10 @@
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
- sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
+ const auto otherOutputBuffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
.WillOnce(Return(mOutputBuffer))
.WillOnce(Return(otherOutputBuffer));
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 5ef5d7b..9aeb290 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -15,6 +15,8 @@
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#include "renderengine/ExternalTexture.h"
+#include "ui/GraphicBuffer.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wextra"
@@ -239,9 +241,9 @@
DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR)));
base::unique_fd fence;
- EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence).get());
+ EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence)->getBuffer().get());
- EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest()->getBuffer().get());
}
/*
@@ -249,8 +251,11 @@
*/
TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = false;
@@ -261,43 +266,45 @@
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesClientComposition) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
+ mRenderEngine, false);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = true;
state.flipClientTarget = false;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequest) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
+ mRenderEngine, false);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = false;
state.flipClientTarget = true;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferYetDequeued) {
@@ -317,27 +324,28 @@
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesNativeWindowQueueBufferFailureOnVirtualDisplay) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
+ mRenderEngine, false);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = true;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(INVALID_OPERATION));
EXPECT_CALL(mDisplay, isVirtual()).WillOnce(Return(true));
- EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
/*
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index f01fe27..283c692 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -305,8 +305,8 @@
const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layers,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> size_t {
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd&&, base::unique_fd*) -> size_t {
EXPECT_EQ(Rect(0, 0, 2, 2), displaySettings.physicalDisplay);
EXPECT_EQ(mOutputState.layerStackSpace.content, displaySettings.clip);
EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.orientation),
@@ -321,7 +321,6 @@
EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1));
EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers));
- EXPECT_CALL(mRenderEngine, cacheExternalTextureBuffer(_));
cachedSet.render(mRenderEngine, mOutputState);
expectReadyBuffer(cachedSet);
@@ -331,7 +330,6 @@
cachedSet.getOutputSpace().bounds);
// Now check that appending a new cached set properly cleans up RenderEngine resources.
- EXPECT_CALL(mRenderEngine, unbindExternalTextureBuffer(_));
CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
cachedSet.append(CachedSet(layer3));
}
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index b7b2cc6..8692ee6 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -70,11 +70,13 @@
mIsPrimary(args.isPrimary) {
mCompositionDisplay->editState().isSecure = args.isSecure;
mCompositionDisplay->createRenderSurface(
- compositionengine::RenderSurfaceCreationArgs{ANativeWindow_getWidth(
- args.nativeWindow.get()),
- ANativeWindow_getHeight(
- args.nativeWindow.get()),
- args.nativeWindow, args.displaySurface});
+ compositionengine::
+ RenderSurfaceCreationArgs{ANativeWindow_getWidth(args.nativeWindow.get()),
+ ANativeWindow_getHeight(args.nativeWindow.get()),
+ args.nativeWindow, args.displaySurface,
+ static_cast<size_t>(
+ SurfaceFlinger::
+ maxFrameBufferAcquiredBuffers)});
if (!mFlinger->mDisableClientCompositionCache &&
SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 829b916..b12e3fb 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1050,7 +1050,7 @@
}
// Allow BufferStateLayer to release any unlatched buffers in drawing state.
- bufferMayChange(c.buffer);
+ bufferMayChange(c.buffer->getBuffer());
// Commit the transaction
commitTransaction(c);
@@ -1062,7 +1062,11 @@
void Layer::commitTransaction(State& stateToCommit) {
if (auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
- mDrawingState.buffer != stateToCommit.buffer && bufferSurfaceFrame != nullptr &&
+ ((mDrawingState.buffer && stateToCommit.buffer &&
+ mDrawingState.buffer->getBuffer() != stateToCommit.buffer->getBuffer()) ||
+ (mDrawingState.buffer && !stateToCommit.buffer) ||
+ (!mDrawingState.buffer && stateToCommit.buffer)) &&
+ bufferSurfaceFrame != nullptr &&
bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
// If the previous buffer was committed but not latched (refreshPending - happens during
// back to back invalidates), it gets silently dropped here. Mark the corresponding
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 64986af..8e51e41 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -208,7 +208,7 @@
Region transparentRegionHint;
- sp<GraphicBuffer> buffer;
+ std::shared_ptr<renderengine::ExternalTexture> buffer;
client_cache_t clientCacheId;
sp<Fence> acquireFence;
std::shared_ptr<FenceTime> acquireFenceTime;
@@ -412,10 +412,11 @@
// Used only to set BufferStateLayer state
virtual bool setTransform(uint32_t /*transform*/) { return false; };
virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; };
- virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/, const sp<Fence>& /*acquireFence*/,
- nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/,
- bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/,
- uint64_t /* frameNumber */, std::optional<nsecs_t> /* dequeueTime */,
+ virtual bool setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& /*buffer*/,
+ const sp<Fence>& /*acquireFence*/, nsecs_t /*postTime*/,
+ nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
+ const client_cache_t& /*clientCacheId*/, uint64_t /* frameNumber */,
+ std::optional<nsecs_t> /* dequeueTime */,
const FrameTimelineInfo& /*info*/,
const sp<ITransactionCompletedListener>& /* releaseBufferListener */) {
return false;
@@ -726,7 +727,7 @@
* Called before updating the drawing state buffer. Used by BufferStateLayer to release any
* unlatched buffers in the drawing state.
*/
- virtual void bufferMayChange(sp<GraphicBuffer>& /* newBuffer */){};
+ virtual void bufferMayChange(const sp<GraphicBuffer>& /* newBuffer */){};
/*
* Remove relative z for the layer if its relative parent is not part of the
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 7a3e433..a9fd16c 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -208,7 +208,8 @@
return true;
}
-const std::vector<sp<GraphicBuffer>>& RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
+const std::vector<std::shared_ptr<renderengine::ExternalTexture>>&
+RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
if (mBufferCache.find(fps) == mBufferCache.end()) {
// Ensure the range is > 0, so we don't divide by 0.
const auto rangeLength = std::max(1u, mHighFps - mLowFps);
@@ -222,7 +223,17 @@
color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale);
color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale);
color.a = ALPHA;
- mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner));
+ auto buffers = SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner);
+ std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures;
+ std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures),
+ [&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> {
+ return std::make_shared<
+ renderengine::ExternalTexture>(buffer,
+ mFlinger.getRenderEngine(),
+ renderengine::ExternalTexture::
+ Usage::READABLE);
+ });
+ mBufferCache.emplace(fps, textures);
}
return mBufferCache[fps];
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index c16cfa0..aa8329c 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -16,13 +16,14 @@
#pragma once
-#include <unordered_map>
-
#include <math/vec4.h>
+#include <renderengine/RenderEngine.h>
#include <ui/Rect.h>
#include <ui/Size.h>
#include <utils/StrongPointer.h>
+#include <unordered_map>
+
#include "Fps.h"
namespace android {
@@ -70,7 +71,8 @@
};
bool createLayer();
- const std::vector<sp<GraphicBuffer>>& getOrCreateBuffers(uint32_t fps);
+ const std::vector<std::shared_ptr<renderengine::ExternalTexture>>& getOrCreateBuffers(
+ uint32_t fps);
SurfaceFlinger& mFlinger;
const sp<Client> mClient;
@@ -78,7 +80,8 @@
sp<IBinder> mIBinder;
sp<IGraphicBufferProducer> mGbp;
- std::unordered_map<int, std::vector<sp<GraphicBuffer>>> mBufferCache;
+ std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>
+ mBufferCache;
std::optional<int> mCurrentFps;
int mFrame = 0;
static constexpr float ALPHA = 0.8f;
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index d0032ac..00090d9 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -438,18 +438,22 @@
mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor);
};
- sp<GraphicBuffer> buffer = nullptr;
- if (mCachedBuffer && mCachedBuffer->getWidth() == sampledBounds.getWidth() &&
- mCachedBuffer->getHeight() == sampledBounds.getHeight()) {
+ std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
+ if (mCachedBuffer && mCachedBuffer->getBuffer()->getWidth() == sampledBounds.getWidth() &&
+ mCachedBuffer->getBuffer()->getHeight() == sampledBounds.getHeight()) {
buffer = mCachedBuffer;
} else {
const uint32_t usage =
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
- buffer = new GraphicBuffer(sampledBounds.getWidth(), sampledBounds.getHeight(),
- PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
- const status_t bufferStatus = buffer->initCheck();
+ sp<GraphicBuffer> graphicBuffer =
+ new GraphicBuffer(sampledBounds.getWidth(), sampledBounds.getHeight(),
+ PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
+ const status_t bufferStatus = graphicBuffer->initCheck();
LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureSample: Buffer failed to allocate: %d",
bufferStatus);
+ buffer = std::make_shared<
+ renderengine::ExternalTexture>(graphicBuffer, mFlinger.getRenderEngine(),
+ renderengine::ExternalTexture::Usage::WRITEABLE);
}
const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
@@ -465,8 +469,8 @@
}
ALOGV("Sampling %zu descriptors", activeDescriptors.size());
- std::vector<float> lumas =
- sampleBuffer(buffer, sampledBounds.leftTop(), activeDescriptors, orientation);
+ std::vector<float> lumas = sampleBuffer(buffer->getBuffer(), sampledBounds.leftTop(),
+ activeDescriptors, orientation);
if (lumas.size() != activeDescriptors.size()) {
ALOGW("collected %zu median luma values for %zu descriptors", lumas.size(),
activeDescriptors.size());
@@ -477,16 +481,6 @@
activeDescriptors[d].listener->onSampleCollected(lumas[d]);
}
- // Extend the lifetime of mCachedBuffer from the previous frame to here to ensure that:
- // 1) The region sampling thread is the last owner of the buffer, and the freeing of the buffer
- // happens in this thread, as opposed to the main thread.
- // 2) The listener(s) receive their notifications prior to freeing the buffer.
- if (mCachedBuffer != nullptr && mCachedBuffer != buffer) {
- if (mFlinger.getRenderEngine().getRenderEngineType() ==
- renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) {
- mFlinger.getRenderEngine().unbindExternalTextureBuffer(mCachedBuffer->getId());
- }
- }
mCachedBuffer = buffer;
ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded));
}
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index 0defdb3..86632db 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -16,17 +16,19 @@
#pragma once
+#include <android-base/thread_annotations.h>
+#include <binder/IBinder.h>
+#include <renderengine/ExternalTexture.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Rect.h>
+#include <utils/StrongPointer.h>
+
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <unordered_map>
-#include <android-base/thread_annotations.h>
-#include <binder/IBinder.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/Rect.h>
-#include <utils/StrongPointer.h>
#include "Scheduler/OneShotTimer.h"
namespace android {
@@ -122,7 +124,8 @@
std::mutex mSamplingMutex;
std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex);
- sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mSamplingMutex) = nullptr;
+ std::shared_ptr<renderengine::ExternalTexture> mCachedBuffer GUARDED_BY(mSamplingMutex) =
+ nullptr;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 02579c6..e66f65b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -735,6 +735,7 @@
mCompositionEngine->setTimeStats(mTimeStats);
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId);
+ ClientCache::getInstance().setRenderEngine(&getRenderEngine());
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
@@ -3707,7 +3708,6 @@
if (uncacheBuffer.isValid()) {
ClientCache::getInstance().erase(uncacheBuffer);
- getRenderEngine().unbindExternalTextureBuffer(uncacheBuffer.id);
}
// If a synchronous transaction is explicitly requested without any changes, force a transaction
@@ -4083,23 +4083,16 @@
}
bool bufferChanged = what & layer_state_t::eBufferChanged;
bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged;
- sp<GraphicBuffer> buffer;
+ std::shared_ptr<renderengine::ExternalTexture> buffer;
if (bufferChanged && cacheIdChanged && s.buffer != nullptr) {
- buffer = s.buffer;
- bool success = ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
- if (success) {
- getRenderEngine().cacheExternalTextureBuffer(s.buffer);
- success = ClientCache::getInstance()
- .registerErasedRecipient(s.cachedBuffer,
- wp<ClientCache::ErasedRecipient>(this));
- if (!success) {
- getRenderEngine().unbindExternalTextureBuffer(s.buffer->getId());
- }
- }
+ ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
+ buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (cacheIdChanged) {
buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (bufferChanged) {
- buffer = s.buffer;
+ buffer = std::make_shared<
+ renderengine::ExternalTexture>(s.buffer, getRenderEngine(),
+ renderengine::ExternalTexture::Usage::READABLE);
}
if (buffer) {
const bool frameNumberChanged = what & layer_state_t::eFrameNumberChanged;
@@ -6003,15 +5996,17 @@
const status_t bufferStatus = buffer->initCheck();
LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d",
bufferStatus);
- return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
+ const auto texture = std::make_shared<
+ renderengine::ExternalTexture>(buffer, getRenderEngine(),
+ renderengine::ExternalTexture::Usage::WRITEABLE);
+ return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, texture,
false /* regionSampling */, grayscale, captureListener);
}
-status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
- TraverseLayersFunction traverseLayers,
- sp<GraphicBuffer>& buffer, bool regionSampling,
- bool grayscale,
- const sp<IScreenCaptureListener>& captureListener) {
+status_t SurfaceFlinger::captureScreenCommon(
+ RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers,
+ const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
+ bool grayscale, const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
if (captureListener == nullptr) {
@@ -6044,15 +6039,6 @@
regionSampling, grayscale, captureResults);
});
- // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine
- // Only do this when we're not doing region sampling, to allow the region sampling thread to
- // manage buffer lifecycle itself.
- if (!regionSampling &&
- getRenderEngine().getRenderEngineType() ==
- renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) {
- getRenderEngine().unbindExternalTextureBuffer(buffer->getId());
- }
-
captureResults.result = result;
captureListener->onScreenCaptureCompleted(captureResults);
}));
@@ -6060,11 +6046,10 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
- TraverseLayersFunction traverseLayers,
- const sp<GraphicBuffer>& buffer, bool forSystem,
- bool regionSampling, bool grayscale,
- ScreenCaptureResults& captureResults) {
+status_t SurfaceFlinger::renderScreenImplLocked(
+ const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
+ const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool forSystem,
+ bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) {
ATRACE_CALL();
traverseLayers([&](Layer* layer) {
@@ -6072,7 +6057,7 @@
captureResults.capturedSecureLayers || (layer->isVisible() && layer->isSecure());
});
- const bool useProtected = buffer->getUsage() & GRALLOC_USAGE_PROTECTED;
+ const bool useProtected = buffer->getBuffer()->getUsage() & GRALLOC_USAGE_PROTECTED;
// We allow the system server to take screenshots of secure layers for
// use in situations like the Screen-rotation animation and place
@@ -6082,7 +6067,7 @@
return PERMISSION_DENIED;
}
- captureResults.buffer = buffer;
+ captureResults.buffer = buffer->getBuffer();
captureResults.capturedDataspace = renderArea.getReqDataSpace();
const auto reqWidth = renderArea.getReqWidth();
@@ -6173,11 +6158,9 @@
base::unique_fd drawFence;
getRenderEngine().useProtectedContext(useProtected);
- // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine
- const bool useFramebufferCache = getRenderEngine().getRenderEngineType() ==
- renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED;
+ const constexpr bool kUseFramebufferCache = false;
getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer,
- useFramebufferCache, std::move(bufferFence), &drawFence);
+ kUseFramebufferCache, std::move(bufferFence), &drawFence);
if (drawFence >= 0) {
sp<Fence> releaseFence = new Fence(dup(drawFence));
@@ -6442,10 +6425,6 @@
mOffscreenLayers.erase(layer);
}
-void SurfaceFlinger::bufferErased(const client_cache_t& clientCacheId) {
- getRenderEngine().unbindExternalTextureBuffer(clientCacheId.id);
-}
-
status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
float lightPosY, float lightPosZ,
float lightRadius) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b3da61e..a242d8a 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -184,7 +184,6 @@
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
- public ClientCache::ErasedRecipient,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback,
private ISchedulerCallback {
@@ -332,9 +331,6 @@
wp<Layer> fromHandle(const sp<IBinder>& handle);
wp<Layer> fromHandleLocked(const sp<IBinder>& handle) const REQUIRES(mStateLock);
- // Inherit from ClientCache::ErasedRecipient
- void bufferErased(const client_cache_t& clientCacheId) override;
-
// If set, disables reusing client composition buffers. This can be set by
// debug.sf.disable_client_composition_cache
bool mDisableClientCompositionCache = false;
@@ -907,12 +903,14 @@
status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize,
ui::PixelFormat, bool allowProtected, bool grayscale,
const sp<IScreenCaptureListener>&);
- status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, sp<GraphicBuffer>&,
+ status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction,
+ const std::shared_ptr<renderengine::ExternalTexture>&,
bool regionSampling, bool grayscale,
const sp<IScreenCaptureListener>&);
status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction,
- const sp<GraphicBuffer>&, bool forSystem, bool regionSampling,
- bool grayscale, ScreenCaptureResults&);
+ const std::shared_ptr<renderengine::ExternalTexture>&,
+ bool forSystem, bool regionSampling, bool grayscale,
+ ScreenCaptureResults&);
sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock);
sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock);
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 4e1c0c7..3042450 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -15,6 +15,7 @@
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#include "renderengine/ExternalTexture.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wextra"
@@ -194,7 +195,7 @@
sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE;
- sp<GraphicBuffer> mCaptureScreenBuffer;
+ std::shared_ptr<renderengine::ExternalTexture> mCaptureScreenBuffer;
};
template <typename LayerCase>
@@ -243,11 +244,15 @@
// TODO: Eliminate expensive/real allocation if possible.
const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
- mCaptureScreenBuffer = new GraphicBuffer(renderArea->getReqWidth(), renderArea->getReqHeight(),
- HAL_PIXEL_FORMAT_RGBA_8888, 1, usage, "screenshot");
+ mCaptureScreenBuffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(renderArea->getReqWidth(),
+ renderArea->getReqHeight(),
+ HAL_PIXEL_FORMAT_RGBA_8888, 1, usage,
+ "screenshot"),
+ *mRenderEngine, true);
status_t result =
- mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer.get(),
+ mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer,
forSystem, regionSampling);
EXPECT_EQ(NO_ERROR, result);
@@ -340,8 +345,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillRepeatedly([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>&,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> status_t {
+ const std::shared_ptr<renderengine::ExternalTexture>&,
+ const bool, base::unique_fd&&, base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -389,8 +394,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillRepeatedly([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>&,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> status_t {
+ const std::shared_ptr<renderengine::ExternalTexture>&,
+ const bool, base::unique_fd&&, base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -625,8 +630,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layerSettings,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> status_t {
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd&&, base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -674,8 +679,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layerSettings,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> status_t {
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd&&, base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -751,8 +756,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layerSettings,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> status_t {
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd&&, base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 63baf7d..d004b9d 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -352,8 +352,8 @@
auto renderScreenImplLocked(const RenderArea& renderArea,
SurfaceFlinger::TraverseLayersFunction traverseLayers,
- const sp<GraphicBuffer>& buffer, bool forSystem,
- bool regionSampling) {
+ const std::shared_ptr<renderengine::ExternalTexture>& buffer,
+ bool forSystem, bool regionSampling) {
ScreenCaptureResults captureResults;
return mFlinger->renderScreenImplLocked(renderArea, traverseLayers, buffer, forSystem,
regionSampling, false /* grayscale */,
diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
index b5ef0a1..690a7fd 100644
--- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
@@ -21,6 +21,8 @@
#include <gtest/gtest.h>
#include <gui/SurfaceComposerClient.h>
#include <log/log.h>
+#include <renderengine/ExternalTexture.h>
+#include <renderengine/mock/RenderEngine.h>
#include <utils/String8.h>
#include "TestableSurfaceFlinger.h"
@@ -102,6 +104,7 @@
TestableSurfaceFlinger mFlinger;
Hwc2::mock::Composer* mComposer = nullptr;
+ renderengine::mock::RenderEngine mRenderEngine;
FenceToFenceTimeMap fenceFactory;
client_cache_t mClientCache;
@@ -109,9 +112,12 @@
sp<BufferStateLayer> layer = createBufferStateLayer();
sp<Fence> fence(new Fence());
- sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
int32_t layerId = layer->getSequence();
- uint64_t bufferId = buffer->getId();
+ uint64_t bufferId = buffer->getBuffer()->getId();
uint64_t frameNumber = 5;
nsecs_t dequeueTime = 10;
nsecs_t postTime = 20;
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index c75538f..6ff6e90 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -21,6 +21,8 @@
#include <gtest/gtest.h>
#include <gui/SurfaceComposerClient.h>
#include <log/log.h>
+#include <renderengine/ExternalTexture.h>
+#include <renderengine/mock/RenderEngine.h>
#include <utils/String8.h>
#include "TestableSurfaceFlinger.h"
@@ -104,6 +106,7 @@
TestableSurfaceFlinger mFlinger;
Hwc2::mock::Composer* mComposer = nullptr;
+ renderengine::mock::RenderEngine mRenderEngine;
FenceToFenceTimeMap fenceFactory;
client_cache_t mClientCache;
@@ -124,7 +127,10 @@
sp<BufferStateLayer> layer = createBufferStateLayer();
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence->signalForTest(12);
@@ -149,7 +155,10 @@
sp<Fence> fence1(new Fence());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
- sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer1 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -158,7 +167,10 @@
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
- sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer2 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
nsecs_t start = systemTime();
layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
@@ -196,8 +208,10 @@
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
-
+ const auto buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence->signalForTest(12);
@@ -222,8 +236,10 @@
sp<BufferStateLayer> layer = createBufferStateLayer();
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
-
+ const auto buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -252,8 +268,10 @@
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
-
+ const auto buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 3, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(2u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -351,7 +369,10 @@
sp<Fence> fence1(new Fence());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
- sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer1 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
@@ -359,7 +380,10 @@
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
- sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer2 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence2->signalForTest(12);
@@ -386,7 +410,10 @@
sp<Fence> fence1(new Fence());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
- sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer1 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -395,7 +422,10 @@
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
- sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer2 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
auto dropStartTime1 = systemTime();
layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ FrameTimelineInfo::INVALID_VSYNC_ID, /*inputEventId*/ 0},
@@ -407,7 +437,10 @@
sp<Fence> fence3(new Fence());
auto acquireFence3 = fenceFactory.createFenceTimeForTest(fence3);
- sp<GraphicBuffer> buffer3{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer3 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+ 1, 0),
+ mRenderEngine, false);
auto dropStartTime2 = systemTime();
layer->setBuffer(buffer3, fence3, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 2, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
@@ -447,7 +480,11 @@
std::vector<std::shared_ptr<frametimeline::SurfaceFrame>> bufferlessSurfaceFrames;
for (int i = 0; i < 10; i += 2) {
sp<Fence> fence1(new Fence());
- sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+ const auto buffer1 = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(1, 1,
+ HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ 0),
+ mRenderEngine, false);
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0},
nullptr /* releaseBufferCallback */);