Revert "Add ExternalTexture class into RenderEngine interface"
Revert submission 14086921-renderengine-external-tex
Reason for revert: Potential culprit for b/185361988
Reverted Changes:
I7796764e2:Update WaylandRenderSurface to accomodate interfac...
I13904eec4:Update Readback VTS to align with RenderEngine int...
I222c71e6e:Add ExternalTexture class into RenderEngine interf...
Change-Id: I1501890f4861a3df7ce273f1fe2ccdb275e2632c
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index f395ab4..ec39137 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -48,7 +48,6 @@
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
deleted file mode 100644
index eabff58..0000000
--- a/libs/renderengine/ExternalTexture.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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 d87315f..a2963a7 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -746,8 +746,7 @@
return;
}
-void GLESRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
- bool /*isRenderable*/) {
+void GLESRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
ATRACE_CALL();
mImageManager->cacheAsync(buffer, nullptr);
}
@@ -798,8 +797,8 @@
return NO_ERROR;
}
-void GLESRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
- mImageManager->releaseAsync(buffer->getId(), nullptr);
+void GLESRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
+ mImageManager->releaseAsync(bufferId, nullptr);
}
std::shared_ptr<ImageManager::Barrier> GLESRenderEngine::unbindExternalTextureBufferForTesting(
@@ -1103,7 +1102,7 @@
status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
+ const sp<GraphicBuffer>& buffer,
const bool useFramebufferCache, base::unique_fd&& bufferFence,
base::unique_fd* drawFence) {
ATRACE_CALL();
@@ -1126,7 +1125,7 @@
return BAD_VALUE;
}
- validateOutputBufferUsage(buffer->getBuffer());
+ validateOutputBufferUsage(buffer);
std::unique_ptr<BindNativeBufferAsFramebuffer> fbo;
// Gathering layers that requested blur, we'll need them to decide when to render to an
@@ -1143,13 +1142,11 @@
if (blurLayersSize == 0) {
fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
- buffer->getBuffer()
- .get()
- ->getNativeBuffer(),
+ buffer.get()->getNativeBuffer(),
useFramebufferCache);
if (fbo->getStatus() != NO_ERROR) {
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors();
return fbo->getStatus();
}
@@ -1160,7 +1157,7 @@
mBlurFilter->setAsDrawTarget(display, blurLayers.front()->backgroundBlurRadius);
if (status != NO_ERROR) {
ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors();
return status;
}
@@ -1197,7 +1194,7 @@
auto status = mBlurFilter->prepare();
if (status != NO_ERROR) {
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors("Can't render first blur pass");
return status;
}
@@ -1206,7 +1203,6 @@
// 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();
@@ -1219,7 +1215,7 @@
}
if (status != NO_ERROR) {
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors("Can't bind native framebuffer");
return status;
}
@@ -1227,7 +1223,7 @@
status = mBlurFilter->render(blurLayersSize > 1);
if (status != NO_ERROR) {
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors("Can't render blur filter");
return status;
}
@@ -1254,7 +1250,7 @@
disableTexture = false;
isOpaque = layer->source.buffer.isOpaque;
- sp<GraphicBuffer> gBuf = layer->source.buffer.buffer->getBuffer();
+ sp<GraphicBuffer> gBuf = layer->source.buffer.buffer;
validateInputBufferUsage(gBuf);
bindExternalTextureBuffer(layer->source.buffer.textureName, gBuf,
layer->source.buffer.fence);
@@ -1278,7 +1274,7 @@
// Do not cache protected EGLImage, protected memory is limited.
if (gBuf->getUsage() & GRALLOC_USAGE_PROTECTED) {
- unmapExternalTextureBuffer(gBuf);
+ unbindExternalTextureBuffer(gBuf->getId());
}
}
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index e7ed9c0..cd7a86b 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -60,14 +60,16 @@
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 std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
+ const sp<GraphicBuffer>& 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; }
@@ -103,9 +105,6 @@
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
deleted file mode 100644
index 07f0833..0000000
--- a/libs/renderengine/include/renderengine/ExternalTexture.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 c54c5ba..7661233 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -16,9 +16,11 @@
#pragma once
+#include <iosfwd>
+
#include <math/mat4.h>
#include <math/vec3.h>
-#include <renderengine/ExternalTexture.h>
+#include <renderengine/Texture.h>
#include <ui/BlurRegion.h>
#include <ui/Fence.h>
#include <ui/FloatRect.h>
@@ -29,8 +31,6 @@
#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.
- std::shared_ptr<ExternalTexture> buffer = nullptr;
+ sp<GraphicBuffer> 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 c8a0f0a..8dd98c3 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -17,20 +17,19 @@
#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).
*/
@@ -52,7 +51,6 @@
namespace renderengine {
-class ExternalTexture;
class Image;
class Mesh;
class Texture;
@@ -106,6 +104,23 @@
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,
@@ -176,9 +191,8 @@
// now, this always returns NO_ERROR.
virtual status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) = 0;
+ const sp<GraphicBuffer>& 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
@@ -199,31 +213,6 @@
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 27dbd1e..228553d 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -39,6 +39,8 @@
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());
@@ -48,17 +50,12 @@
MOCK_METHOD1(cleanupPostRender, bool(CleanupMode mode));
MOCK_METHOD6(drawLayers,
status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&,
- const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&,
+ const sp<GraphicBuffer>&, 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 2d61cf8..bb75878 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,18 +41,13 @@
// of shared ownership with Skia objects, so we wrap it here instead.
class LocalRef {
public:
- LocalRef(AutoBackendTexture* texture) { setTexture(texture); }
+ LocalRef() {}
~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) {
@@ -64,6 +59,12 @@
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 1c2b2fc..1db20c0 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,
- const std::shared_ptr<ExternalTexture>& dstTexture) {
+ sp<GraphicBuffer> dstBuffer) {
// 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, dstTexture, kUseFrameBufferCache, base::unique_fd(),
+ renderengine->drawLayers(display, layers, dstBuffer, 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,14 +86,13 @@
// clang-format on
for (auto translucent : {false, true}) {
layer.shadow.casterIsTranslucent = translucent;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- const std::shared_ptr<ExternalTexture>& dstTexture,
- const std::shared_ptr<ExternalTexture>& srcTexture) {
+ sp<GraphicBuffer> dstBuffer, sp<GraphicBuffer> srcBuffer) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -104,7 +103,7 @@
},
.source = PixelSource{.buffer =
Buffer{
- .buffer = srcTexture,
+ .buffer = srcBuffer,
.maxMasteringLuminance = 1000.f,
.maxContentLuminance = 1000.f,
}},
@@ -127,7 +126,7 @@
layer.source.buffer.isOpaque = isOpaque;
for (auto alpha : {half(.23999f), half(1.0f)}) {
layer.alpha = alpha;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
@@ -136,7 +135,7 @@
}
static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- const std::shared_ptr<ExternalTexture>& dstTexture) {
+ sp<GraphicBuffer> dstBuffer) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -144,11 +143,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};
@@ -156,14 +155,14 @@
layer.geometry.positionTransform = transform;
for (float roundedCornersRadius : {0.0f, 0.05f, 50.f}) {
layer.geometry.roundedCornersRadius = roundedCornersRadius;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
}
static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- const std::shared_ptr<ExternalTexture>& dstTexture) {
+ sp<GraphicBuffer> dstBuffer) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -177,7 +176,7 @@
auto layers = std::vector<const LayerSettings*>{&layer};
for (int radius : {9, 60}) {
layer.backgroundBlurRadius = radius;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
@@ -215,9 +214,6 @@
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
@@ -226,16 +222,11 @@
new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
usage, "drawImageLayer_src");
- 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);
+ drawSolidLayers(renderengine, display, dstBuffer);
+ drawShadowLayers(renderengine, display, srcBuffer);
+ drawBlurLayers(renderengine, display, dstBuffer);
// The majority of shaders are related to sampling images.
- drawImageLayers(renderengine, display, dstTexture, srcTexture);
+ drawImageLayers(renderengine, display, dstBuffer, srcBuffer);
// should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
@@ -243,12 +234,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, dstTexture, externalTexture);
+ drawImageLayers(renderengine, display, dstBuffer, externalBuffer);
+ renderengine->unbindExternalTextureBuffer(externalBuffer->getId());
+
+ renderengine->unbindExternalTextureBuffer(srcBuffer->getId());
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 e781584..3b2c7e5 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -329,6 +329,8 @@
}
SkiaGLRenderEngine::~SkiaGLRenderEngine() {
+ cleanFramebufferCache();
+
std::lock_guard<std::mutex> lock(mRenderingMutex);
if (mBlurFilter) {
delete mBlurFilter;
@@ -482,8 +484,7 @@
sourceTransfer != destTransfer;
}
-void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
- bool isRenderable) {
+void SkiaGLRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
// 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) {
@@ -504,41 +505,25 @@
auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
std::lock_guard<std::mutex> lock(mRenderingMutex);
- mGraphicBufferExternalRefs[buffer->getId()]++;
-
- if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
+ auto iter = cache.find(buffer->getId());
+ if (iter != cache.end()) {
+ ALOGV("Texture already exists in cache.");
+ } else {
std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
- std::make_shared<AutoBackendTexture::LocalRef>(
- new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(),
- isRenderable));
+ std::make_shared<AutoBackendTexture::LocalRef>();
+ imageTextureRef->setTexture(
+ new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), false));
cache.insert({buffer->getId(), imageTextureRef});
}
// restore the original state of the protected context if necessary
useProtectedContext(protectedContextState);
}
-void SkiaGLRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+void SkiaGLRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mRenderingMutex);
- 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());
- }
- }
+ mTextureCache.erase(bufferId);
+ mProtectedTextureCache.erase(bufferId);
}
sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> shader,
@@ -636,8 +621,8 @@
status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool /*useFramebufferCache*/,
+ const sp<GraphicBuffer>& buffer,
+ const bool useFramebufferCache,
base::unique_fd&& bufferFence, base::unique_fd* drawFence) {
ATRACE_NAME("SkiaGL::drawLayers");
@@ -660,18 +645,32 @@
return BAD_VALUE;
}
- validateOutputBufferUsage(buffer->getBuffer());
+ validateOutputBufferUsage(buffer);
auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
+ AHardwareBuffer_Desc bufferDesc;
+ AHardwareBuffer_describe(buffer->toAHardwareBuffer(), &bufferDesc);
- 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));
+ 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});
+ }
}
const ui::Dataspace dstDataspace =
@@ -877,22 +876,18 @@
SkPaint paint;
if (layer->source.buffer.buffer) {
ATRACE_NAME("DrawImage");
- validateInputBufferUsage(layer->source.buffer.buffer->getBuffer());
+ validateInputBufferUsage(layer->source.buffer.buffer);
const auto& item = layer->source.buffer;
std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = nullptr;
-
- if (const auto& iter = cache.find(item.buffer->getBuffer()->getId());
- iter != cache.end()) {
+ auto iter = cache.find(item.buffer->getId());
+ if (iter != cache.end()) {
imageTextureRef = iter->second;
} else {
- // 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));
+ imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
+ imageTextureRef->setTexture(new AutoBackendTexture(grContext.get(),
+ item.buffer->toAHardwareBuffer(),
+ false));
+ cache.insert({item.buffer->getId(), imageTextureRef});
}
sk_sp<SkImage> image =
@@ -1205,6 +1200,15 @@
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);
@@ -1277,12 +1281,6 @@
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 e71c560..8e77c16 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -23,7 +23,6 @@
#include <GrDirectContext.h>
#include <SkSurface.h>
#include <android-base/thread_annotations.h>
-#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <sys/types.h>
@@ -53,12 +52,13 @@
~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 std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
- void cleanFramebufferCache() override {}
+ const sp<GraphicBuffer>& 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,8 +72,6 @@
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);
@@ -116,9 +114,7 @@
const PixelFormat mDefaultPixelFormat;
const bool mUseColorManagement;
- // 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.
+ // Cache of GL textures that we'll store per GraphicBuffer ID
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 308c5ff..51ef088 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -42,12 +42,15 @@
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 std::shared_ptr<ExternalTexture>& /*buffer*/,
+ const sp<GraphicBuffer>& /*buffer*/,
const bool /*useFramebufferCache*/,
base::unique_fd&& /*bufferFence*/,
base::unique_fd* /*drawFence*/) override {
@@ -57,11 +60,6 @@
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 d63c88b..7846156 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -24,7 +24,6 @@
#include <cutils/properties.h>
#include <gtest/gtest.h>
-#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <sync/sync.h>
#include <ui/PixelFormat.h>
@@ -161,42 +160,27 @@
class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
public:
- 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);
+ 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");
}
// Allocates a 1x1 buffer to fill with a solid color
- 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);
+ 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");
}
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() {
@@ -227,21 +211,20 @@
}
uint8_t* pixels;
- mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
file << "P6\n";
- file << mBuffer->getBuffer()->getWidth() << "\n";
- file << mBuffer->getBuffer()->getHeight() << "\n";
+ file << mBuffer->getWidth() << "\n";
+ file << mBuffer->getHeight() << "\n";
file << 255 << "\n";
- std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
- mBuffer->getBuffer()->getHeight() * 3);
+ std::vector<uint8_t> outBuffer(mBuffer->getWidth() * mBuffer->getHeight() * 3);
auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
- 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++) {
+ 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++) {
// Only copy R, G and B components
outPtr[0] = src[0];
outPtr[1] = src[1];
@@ -252,7 +235,7 @@
}
}
file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
- mBuffer->getBuffer()->unlock();
+ mBuffer->unlock();
}
void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
@@ -279,13 +262,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->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ mBuffer->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->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
+ const uint8_t* src =
+ pixels + (mBuffer->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);
@@ -306,7 +289,7 @@
break;
}
}
- mBuffer->getBuffer()->unlock();
+ mBuffer->unlock();
}
void expectAlpha(const Rect& rect, uint8_t a) {
@@ -404,6 +387,7 @@
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) {
@@ -413,7 +397,7 @@
ASSERT_EQ(NO_ERROR, status);
if (layers.size() > 0 && mGLESRE != nullptr) {
- ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
+ ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId()));
}
}
@@ -519,11 +503,17 @@
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;
};
@@ -540,7 +530,6 @@
} else {
mRE = renderEngineFactory->createRenderEngine();
}
- mBuffer = allocateDefaultBuffer();
}
struct ColorSourceVariant {
@@ -577,18 +566,18 @@
struct BufferSourceVariant {
static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
RenderEngineTest* fixture) {
- const auto buf = fixture->allocateSourceBuffer(1, 1);
+ sp<GraphicBuffer> buf = RenderEngineTest::allocateSourceBuffer(1, 1);
uint32_t texName;
fixture->mRE->genTextures(1, &texName);
fixture->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
- 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++) {
+ 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++) {
iter[0] = uint8_t(r * 255);
iter[1] = uint8_t(g * 255);
iter[2] = uint8_t(b * 255);
@@ -597,7 +586,7 @@
}
}
- buf->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1023,14 +1012,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.
- const auto buf = allocateSourceBuffer(2, 2);
+ sp<GraphicBuffer> buf = allocateSourceBuffer(2, 2);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->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;
@@ -1044,7 +1033,7 @@
pixels[9] = 0;
pixels[10] = 255;
pixels[11] = 255;
- buf->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1072,19 +1061,19 @@
std::vector<const renderengine::LayerSettings*> layers;
renderengine::LayerSettings layer;
- const auto buf = allocateSourceBuffer(1, 1);
+ sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->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->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1111,19 +1100,19 @@
std::vector<const renderengine::LayerSettings*> layers;
renderengine::LayerSettings layer;
- const auto buf = allocateSourceBuffer(1, 1);
+ sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->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->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1244,7 +1233,8 @@
}
TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
- initializeRenderEngine();
+ const auto& renderEngineFactory = GetParam();
+ mRE = renderEngineFactory->createRenderEngine();
renderengine::DisplaySettings settings;
settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
@@ -1305,6 +1295,7 @@
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);
}
@@ -1332,8 +1323,9 @@
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->getBuffer()->getId()));
+ ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId()));
expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
}
@@ -1582,6 +1574,98 @@
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();
@@ -1774,7 +1858,7 @@
sync_wait(fd, -1);
}
- uint64_t bufferId = layer.source.buffer.buffer->getBuffer()->getId();
+ uint64_t bufferId = layer.source.buffer.buffer->getId();
uint32_t texName = layer.source.buffer.textureName;
EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId));
EXPECT_EQ(bufferId, mGLESRE->getBufferIdForTextureNameForTesting(texName));
@@ -1882,16 +1966,16 @@
// The next layer will overwrite redLayer with a GraphicBuffer that is green
// applied with a translucent alpha.
- const auto buf = allocateSourceBuffer(1, 1);
+ auto buf = allocateSourceBuffer(1, 1);
{
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->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->getBuffer()->unlock();
+ buf->unlock();
}
const renderengine::LayerSettings greenLayer{
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index e3917cc..b093e88 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -162,18 +162,15 @@
TEST_F(RenderEngineThreadedTest, drawLayers) {
renderengine::DisplaySettings settings;
std::vector<const renderengine::LayerSettings*> layers;
- std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(), *mRenderEngine,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
base::unique_fd bufferFence;
base::unique_fd drawFence;
EXPECT_CALL(*mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings&,
const std::vector<const renderengine::LayerSettings*>&,
- const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
- base::unique_fd&&, base::unique_fd*) -> status_t { return NO_ERROR; });
+ const sp<GraphicBuffer>&, 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 c9f6296..194c7da 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -157,28 +157,27 @@
resultFuture.wait();
}
-void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
- bool isRenderable) {
+void RenderEngineThreaded::cacheExternalTextureBuffer(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::mapExternalTextureBuffer");
- instance.mapExternalTextureBuffer(buffer, isRenderable);
+ ATRACE_NAME("REThreaded::cacheExternalTextureBuffer");
+ instance.cacheExternalTextureBuffer(buffer);
});
}
mCondition.notify_one();
}
-void RenderEngineThreaded::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+void RenderEngineThreaded::unbindExternalTextureBuffer(uint64_t bufferId) {
// 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::unmapExternalTextureBuffer");
- instance.unmapExternalTextureBuffer(buffer);
+ ATRACE_NAME("REThreaded::unbindExternalTextureBuffer");
+ instance.unbindExternalTextureBuffer(bufferId);
});
}
mCondition.notify_one();
@@ -240,7 +239,7 @@
status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
+ const sp<GraphicBuffer>& 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 eb6098e..61ae9b8 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -48,6 +48,8 @@
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;
@@ -58,19 +60,14 @@
status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
+ const sp<GraphicBuffer>& 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;