Add extra tests for renderengine
* Test buffer binding methods
* Test caching, and fix a bug caught by these tests.
Test: librenderengine_test
Change-Id: I50623d3a3f0b77f541044354c70db9fb536e66c3
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 48854e2..f651309 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -432,10 +432,15 @@
}
GLESRenderEngine::~GLESRenderEngine() {
- for (const auto& image : mFramebufferImageCache) {
- eglDestroyImageKHR(mEGLDisplay, image.second);
+ std::lock_guard<std::mutex> lock(mRenderingMutex);
+ unbindFrameBuffer(mDrawingBuffer.get());
+ mDrawingBuffer = nullptr;
+ while (!mFramebufferImageCache.empty()) {
+ EGLImageKHR expired = mFramebufferImageCache.front().second;
+ mFramebufferImageCache.pop_front();
+ eglDestroyImageKHR(mEGLDisplay, expired);
}
- mFramebufferImageCache.clear();
+ mImageCache.clear();
eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglTerminate(mEGLDisplay);
}
@@ -634,6 +639,9 @@
status_t GLESRenderEngine::bindExternalTextureBufferLocked(uint32_t texName,
sp<GraphicBuffer> buffer,
sp<Fence> bufferFence) {
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
ATRACE_CALL();
auto cachedImage = mImageCache.find(buffer->getId());
@@ -779,7 +787,7 @@
EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer,
bool isProtected) {
sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(nativeBuffer);
- uint32_t bufferId = graphicBuffer->getId();
+ uint64_t bufferId = graphicBuffer->getId();
for (const auto& image : mFramebufferImageCache) {
if (image.first == bufferId) {
return image.second;
@@ -818,6 +826,11 @@
sync_wait(bufferFence.get(), -1);
}
+ if (buffer == nullptr) {
+ ALOGE("No output buffer provided. Aborting GPU composition.");
+ return BAD_VALUE;
+ }
+
{
std::lock_guard<std::mutex> lock(mRenderingMutex);
@@ -914,10 +927,12 @@
}
}
- *drawFence = flush();
+ if (drawFence != nullptr) {
+ *drawFence = flush();
+ }
// If flush failed or we don't support native fences, we need to force the
// gl command stream to be executed.
- if (drawFence->get() < 0) {
+ if (drawFence == nullptr || drawFence->get() < 0) {
bool success = finish();
if (!success) {
ALOGE("Failed to flush RenderEngine commands");
@@ -1343,6 +1358,20 @@
return (isInputHdrDataSpace || isOutputHdrDataSpace) && inputTransfer != outputTransfer;
}
+bool GLESRenderEngine::isImageCachedForTesting(uint64_t bufferId) {
+ std::lock_guard<std::mutex> lock(mRenderingMutex);
+ const auto& cachedImage = mImageCache.find(bufferId);
+ return cachedImage != mImageCache.end();
+}
+
+bool GLESRenderEngine::isFramebufferImageCachedForTesting(uint64_t bufferId) {
+ std::lock_guard<std::mutex> lock(mRenderingMutex);
+ return std::any_of(mFramebufferImageCache.cbegin(), mFramebufferImageCache.cend(),
+ [=](std::pair<uint64_t, EGLImageKHR> image) {
+ return image.first == bufferId;
+ });
+}
+
// FlushTracer implementation
GLESRenderEngine::FlushTracer::FlushTracer(GLESRenderEngine* engine) : mEngine(engine) {
mThread = std::thread(&GLESRenderEngine::FlushTracer::loop, this);