Merge "Use GLint from client state parameters in glGetBooleanv"
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index 93f9d5d..edaa363 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -1481,7 +1481,7 @@
return GL_NO_ERROR;
}
-void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image) {
+void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image, int width, int height) {
(void)image;
if (target == GL_RENDERBUFFER) {
@@ -1489,7 +1489,7 @@
setBoundRenderbufferEGLImageBacked();
setBoundRenderbufferFormat(GL_RGBA);
setBoundRenderbufferSamples(0);
- setBoundRenderbufferDimensions(1, 1);
+ setBoundRenderbufferDimensions(width, height);
} else {
GLuint texture = getBoundTexture(target);
TextureRec* texrec = getTextureRec(texture);
@@ -1499,7 +1499,7 @@
setBoundTextureFormat(target, GL_RGBA);
setBoundTextureType(target, GL_UNSIGNED_BYTE);
setBoundTextureSamples(target, 0);
- setBoundTextureDims(target, target, 0, 1, 1, 1);
+ setBoundTextureDims(target, target, 0, width, height, 1);
}
}
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index c0ca53a..ff20287 100644
--- a/shared/OpenglCodecCommon/GLClientState.h
+++ b/shared/OpenglCodecCommon/GLClientState.h
@@ -414,7 +414,7 @@
// For accurate error detection, bindTexture should be called for *all*
// targets, not just 2D and EXTERNAL_OES.
GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
- void setBoundEGLImage(GLenum target, GLeglImageOES image);
+ void setBoundEGLImage(GLenum target, GLeglImageOES image, int width, int height);
// Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
GLuint getBoundTexture(GLenum target) const;
diff --git a/shared/OpenglCodecCommon/GLSharedGroup.h b/shared/OpenglCodecCommon/GLSharedGroup.h
index 807a006..9832378 100755
--- a/shared/OpenglCodecCommon/GLSharedGroup.h
+++ b/shared/OpenglCodecCommon/GLSharedGroup.h
@@ -30,6 +30,7 @@
#include <GLES2/gl2ext.h>
#include <map>
+#include <memory>
#include <string>
#include <vector>
@@ -39,7 +40,6 @@
#include <utils/threads.h>
#include "auto_goldfish_dma_context.h"
#include "IndexRangeCache.h"
-#include "SmartPtr.h"
#include "StateTrackingSupport.h"
struct BufferData {
@@ -258,6 +258,6 @@
int getActiveAttributesCountForProgram(GLuint program);
};
-typedef SmartPtr<GLSharedGroup> GLSharedGroupPtr;
+typedef std::shared_ptr<GLSharedGroup> GLSharedGroupPtr;
#endif //_GL_SHARED_GROUP_H_
diff --git a/shared/OpenglCodecCommon/SmartPtr.h b/shared/OpenglCodecCommon/SmartPtr.h
deleted file mode 100644
index 3d821c8..0000000
--- a/shared/OpenglCodecCommon/SmartPtr.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-* Copyright (C) 2011 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.
-*/
-#ifndef __SMART_PTR_H
-#define __SMART_PTR_H
-
-#include <PortableMutex.h>
-
-#include <cutils/atomic.h>
-
-template <class T, bool threadSafe = false>
-class SmartPtr
-{
-public:
- explicit SmartPtr(T* ptr = (T*)NULL) {
- if (threadSafe) {
- m_lock = new mutex_t;
- mutex_init(m_lock);
- }
- else m_lock = NULL;
-
- m_ptr = ptr;
- if (ptr)
- m_pRefCount = new int32_t(1);
- else
- m_pRefCount = NULL;
- }
-
- SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) {
- if (threadSafe) {
- m_lock = new mutex_t;
- mutex_init(m_lock);
- }
- else m_lock = NULL;
-
- m_pRefCount = rhs.m_pRefCount;
- m_ptr = rhs.m_ptr;
- use();
- }
-
- SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) {
- if (threadSafe) {
- m_lock = new mutex_t;
- mutex_init(m_lock);
- }
- else m_lock = NULL;
-
- if (rhs.m_lock) mutex_lock(rhs.m_lock);
- m_pRefCount = rhs.m_pRefCount;
- m_ptr = rhs.m_ptr;
- use();
- if (rhs.m_lock) mutex_unlock(rhs.m_lock);
- }
-
- ~SmartPtr() {
- if (m_lock) mutex_lock(m_lock);
- release();
- if (m_lock)
- {
- mutex_unlock(m_lock);
- mutex_destroy(m_lock);
- delete m_lock;
- }
- }
-
- T* Ptr() const {
- return m_ptr;
- }
-
- const T* constPtr() const
- {
- return m_ptr;
- }
-
- T* operator->() const {
- return m_ptr;
- }
-
- T& operator*() const {
- return *m_ptr;
- }
-
- operator void*() const {
- return (void *)m_ptr;
- }
-
- // This gives STL lists something to compare.
- bool operator <(const SmartPtr<T>& t1) const {
- return m_ptr < t1.m_ptr;
- }
-
- SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs)
- {
- if (m_ptr == rhs.m_ptr)
- return *this;
-
- if (m_lock) mutex_lock(m_lock);
- release();
- m_pRefCount = rhs.m_pRefCount;
- m_ptr = rhs.m_ptr;
- use();
- if (m_lock) mutex_unlock(m_lock);
-
- return *this;
- }
-
- SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs)
- {
- if (m_ptr == rhs.m_ptr)
- return *this;
-
- if (m_lock) mutex_lock(m_lock);
- release();
- if (rhs.m_lock) mutex_lock(rhs.m_lock);
- m_pRefCount = rhs.m_pRefCount;
- m_ptr = rhs.m_ptr;
- use();
- if (rhs.m_lock) mutex_unlock(rhs.m_lock);
- if (m_lock) mutex_unlock(m_lock);
-
- return *this;
- }
-
-private:
- int32_t *m_pRefCount;
- mutex_t *m_lock;
- T* m_ptr;
-
- // Increment the reference count on this pointer by 1.
- int use() {
- if (!m_pRefCount) return 0;
- return android_atomic_inc(m_pRefCount) + 1;
- }
-
- // Decrement the reference count on the pointer by 1.
- // If the reference count goes to (or below) 0, the pointer is deleted.
- int release() {
- if (!m_pRefCount) return 0;
-
- int iVal = android_atomic_dec(m_pRefCount);
- if (iVal > 1)
- return iVal - 1;
-
- delete m_pRefCount;
- m_pRefCount = NULL;
-
- if (m_ptr) {
- delete m_ptr;
- m_ptr = NULL;
- }
- return 0;
- }
-
-};
-
-#endif // of __SMART_PTR_H
diff --git a/system/GLESv1_enc/GLEncoder.h b/system/GLESv1_enc/GLEncoder.h
index a26636c..7837838 100644
--- a/system/GLESv1_enc/GLEncoder.h
+++ b/system/GLESv1_enc/GLEncoder.h
@@ -33,7 +33,7 @@
}
void setSharedGroup(GLSharedGroupPtr shared) {
m_shared = shared;
- if (m_state && m_shared.Ptr())
+ if (m_state && m_shared)
m_state->setTextureData(m_shared->getTextureData());
}
void flush() { m_stream->flush(); }
diff --git a/system/GLESv2/gl2.cpp b/system/GLESv2/gl2.cpp
index 1c5ece7..9598a30 100644
--- a/system/GLESv2/gl2.cpp
+++ b/system/GLESv2/gl2.cpp
@@ -79,7 +79,7 @@
DEFINE_AND_VALIDATE_HOST_CONNECTION();
ctx->override2DTextureTarget(target);
- ctx->associateEGLImage(target, hostImage);
+ ctx->associateEGLImage(target, hostImage, image->width, image->height);
rcEnc->rcBindTexture(rcEnc,
grallocHelper->getHostHandle(native_buffer->handle));
ctx->restore2DTextureTarget(target);
@@ -87,7 +87,7 @@
else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
GET_CONTEXT;
ctx->override2DTextureTarget(target);
- ctx->associateEGLImage(target, hostImage);
+ ctx->associateEGLImage(target, hostImage, image->width, image->height);
ctx->m_glEGLImageTargetTexture2DOES_enc(self, GL_TEXTURE_2D, hostImage);
ctx->restore2DTextureTarget(target);
}
@@ -116,7 +116,7 @@
DEFINE_AND_VALIDATE_HOST_CONNECTION();
GET_CONTEXT;
- ctx->associateEGLImage(target, hostImage);
+ ctx->associateEGLImage(target, hostImage, image->width, image->height);
rcEnc->rcBindRenderbuffer(rcEnc,
grallocHelper->getHostHandle(native_buffer->handle));
} else {
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index add8425..ecc0495 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -41,7 +41,7 @@
static GLubyte *gExtensionsString= (GLubyte *) "GL_OES_EGL_image_external ";
#define SET_ERROR_IF(condition, err) if((condition)) { \
- ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
+ ALOGE("%s:%s:%d GL error 0x%x condition [%s]\n", __FILE__, __FUNCTION__, __LINE__, err, #condition); \
ctx->setError(err); \
return; \
}
@@ -74,6 +74,7 @@
m_currMajorVersion = 2;
m_currMinorVersion = 0;
m_hasAsyncUnmapBuffer = false;
+ m_hasSyncBufferData = false;
m_initialized = false;
m_noHostError = false;
m_state = NULL;
@@ -668,7 +669,11 @@
ctx->m_shared->updateBufferData(bufferId, size, data);
ctx->m_shared->setBufferUsage(bufferId, usage);
- ctx->m_glBufferData_enc(self, target, size, data, usage);
+ if (ctx->m_hasSyncBufferData) {
+ ctx->glBufferDataSyncAEMU(self, target, size, data, usage);
+ } else {
+ ctx->m_glBufferData_enc(self, target, size, data, usage);
+ }
}
void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
@@ -2851,8 +2856,8 @@
}
}
-void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage) {
- m_state->setBoundEGLImage(target, eglImage);
+void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage, int width, int height) {
+ m_state->setBoundEGLImage(target, eglImage, width, height);
}
@@ -6110,6 +6115,18 @@
GLuint tex = ctx->m_state->getBoundTexture(target);
GLsizei neededWidth = xoffset + width;
GLsizei neededHeight = yoffset + height;
+ ALOGD("%s: tex %u needed width height %d %d xoff %d width %d yoff %d height %d (texture width %d height %d) level %d\n", __func__,
+ tex,
+ neededWidth,
+ neededHeight,
+ xoffset,
+ width,
+ yoffset,
+ height,
+ ctx->m_state->queryTexWidth(level, tex),
+ ctx->m_state->queryTexWidth(level, tex),
+ level);
+
SET_ERROR_IF(tex &&
(neededWidth > ctx->m_state->queryTexWidth(level, tex) ||
neededHeight > ctx->m_state->queryTexHeight(level, tex)),
diff --git a/system/GLESv2_enc/GL2Encoder.h b/system/GLESv2_enc/GL2Encoder.h
index 93108eb..90978be 100644
--- a/system/GLESv2_enc/GL2Encoder.h
+++ b/system/GLESv2_enc/GL2Encoder.h
@@ -35,6 +35,9 @@
void setHasAsyncUnmapBuffer(int version) {
m_hasAsyncUnmapBuffer = version;
}
+ void setHasSyncBufferData(bool value) {
+ m_hasSyncBufferData = value;
+ }
void setNoHostError(bool noHostError) {
m_noHostError = noHostError;
}
@@ -62,7 +65,7 @@
}
void setSharedGroup(GLSharedGroupPtr shared) {
m_shared = shared;
- if (m_state && m_shared.Ptr()) {
+ if (m_state && m_shared) {
m_state->setTextureData(m_shared->getTextureData());
m_state->setRenderbufferInfo(m_shared->getRenderbufferInfo());
m_state->setSamplerInfo(m_shared->getSamplerInfo());
@@ -94,7 +97,7 @@
void override2DTextureTarget(GLenum target);
void restore2DTextureTarget(GLenum target);
- void associateEGLImage(GLenum target, GLeglImageOES eglImage);
+ void associateEGLImage(GLenum target, GLeglImageOES eglImage, int width, int height);
// Convenience functions for buffers
GLuint boundBuffer(GLenum target) const;
@@ -113,6 +116,7 @@
std::vector<std::string> m_currExtensionsArray;
bool m_hasAsyncUnmapBuffer;
+ bool m_hasSyncBufferData;
bool m_initialized;
bool m_noHostError;
GLClientState *m_state;
diff --git a/system/GLESv2_enc/gl2_client_context.cpp b/system/GLESv2_enc/gl2_client_context.cpp
index aaa0325..49b52a7 100644
--- a/system/GLESv2_enc/gl2_client_context.cpp
+++ b/system/GLESv2_enc/gl2_client_context.cpp
@@ -436,6 +436,7 @@
glDrawElementsDataNullAEMU = (glDrawElementsDataNullAEMU_client_proc_t) getProc("glDrawElementsDataNullAEMU", userData);
glUnmapBufferAsyncAEMU = (glUnmapBufferAsyncAEMU_client_proc_t) getProc("glUnmapBufferAsyncAEMU", userData);
glFlushMappedBufferRangeAEMU2 = (glFlushMappedBufferRangeAEMU2_client_proc_t) getProc("glFlushMappedBufferRangeAEMU2", userData);
+ glBufferDataSyncAEMU = (glBufferDataSyncAEMU_client_proc_t) getProc("glBufferDataSyncAEMU", userData);
return 0;
}
diff --git a/system/GLESv2_enc/gl2_client_context.h b/system/GLESv2_enc/gl2_client_context.h
index 575395a..b3d5f70 100644
--- a/system/GLESv2_enc/gl2_client_context.h
+++ b/system/GLESv2_enc/gl2_client_context.h
@@ -436,6 +436,7 @@
glDrawElementsDataNullAEMU_client_proc_t glDrawElementsDataNullAEMU;
glUnmapBufferAsyncAEMU_client_proc_t glUnmapBufferAsyncAEMU;
glFlushMappedBufferRangeAEMU2_client_proc_t glFlushMappedBufferRangeAEMU2;
+ glBufferDataSyncAEMU_client_proc_t glBufferDataSyncAEMU;
virtual ~gl2_client_context_t() {}
typedef gl2_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
diff --git a/system/GLESv2_enc/gl2_client_proc.h b/system/GLESv2_enc/gl2_client_proc.h
index 615b123..268cb99 100644
--- a/system/GLESv2_enc/gl2_client_proc.h
+++ b/system/GLESv2_enc/gl2_client_proc.h
@@ -438,6 +438,7 @@
typedef void (gl2_APIENTRY *glDrawElementsDataNullAEMU_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, void*, GLuint);
typedef void (gl2_APIENTRY *glUnmapBufferAsyncAEMU_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, void*, GLboolean*);
typedef void (gl2_APIENTRY *glFlushMappedBufferRangeAEMU2_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, void*);
+typedef GLboolean (gl2_APIENTRY *glBufferDataSyncAEMU_client_proc_t) (void * ctx, GLenum, GLsizeiptr, const GLvoid*, GLenum);
#endif
diff --git a/system/GLESv2_enc/gl2_enc.cpp b/system/GLESv2_enc/gl2_enc.cpp
index d997f29..e610c86 100644
--- a/system/GLESv2_enc/gl2_enc.cpp
+++ b/system/GLESv2_enc/gl2_enc.cpp
@@ -11918,6 +11918,52 @@
}
+GLboolean glBufferDataSyncAEMU_enc(void *self , GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ AEMU_SCOPED_TRACE("glBufferDataSyncAEMU encode");
+
+ gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+ IOStream *stream = ctx->m_stream;
+ ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+ bool useChecksum = checksumCalculator->getVersion() > 0;
+
+ const unsigned int __size_data = ((data != NULL) ? size : 0);
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 4 + __size_data + 4 + 1*4;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_glBufferDataSyncAEMU;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &target, 4); ptr += 4;
+ memcpy(ptr, &size, 4); ptr += 4;
+ memcpy(ptr, &__size_data, 4); ptr += 4;
+ if (data != NULL) memcpy(ptr, data, __size_data);ptr += __size_data;
+ memcpy(ptr, &usage, 4); ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+ GLboolean retval;
+ stream->readback(&retval, 1);
+ if (useChecksum) checksumCalculator->addBuffer(&retval, 1);
+ if (useChecksum) {
+ unsigned char *checksumBufPtr = NULL;
+ unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+ if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+ stream->readback(checksumBufPtr, checksumSize);
+ if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+ ALOGE("glBufferDataSyncAEMU: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+ return retval;
+}
+
} // namespace
gl2_encoder_context_t::gl2_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator)
@@ -12351,5 +12397,6 @@
this->glDrawElementsDataNullAEMU = &glDrawElementsDataNullAEMU_enc;
this->glUnmapBufferAsyncAEMU = &glUnmapBufferAsyncAEMU_enc;
this->glFlushMappedBufferRangeAEMU2 = &glFlushMappedBufferRangeAEMU2_enc;
+ this->glBufferDataSyncAEMU = &glBufferDataSyncAEMU_enc;
}
diff --git a/system/GLESv2_enc/gl2_entry.cpp b/system/GLESv2_enc/gl2_entry.cpp
index a5d6c87..5ea44c2 100644
--- a/system/GLESv2_enc/gl2_entry.cpp
+++ b/system/GLESv2_enc/gl2_entry.cpp
@@ -431,6 +431,7 @@
void glDrawElementsDataNullAEMU(GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen);
void glUnmapBufferAsyncAEMU(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* guest_buffer, GLboolean* out_res);
void glFlushMappedBufferRangeAEMU2(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* guest_buffer);
+ GLboolean glBufferDataSyncAEMU(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
};
#ifndef GET_CONTEXT
@@ -3032,3 +3033,9 @@
ctx->glFlushMappedBufferRangeAEMU2(ctx, target, offset, length, access, guest_buffer);
}
+GLboolean glBufferDataSyncAEMU(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ GET_CONTEXT;
+ return ctx->glBufferDataSyncAEMU(ctx, target, size, data, usage);
+}
+
diff --git a/system/GLESv2_enc/gl2_opcodes.h b/system/GLESv2_enc/gl2_opcodes.h
index 9c619e1..25ab3e7 100644
--- a/system/GLESv2_enc/gl2_opcodes.h
+++ b/system/GLESv2_enc/gl2_opcodes.h
@@ -429,7 +429,8 @@
#define OP_glDrawElementsDataNullAEMU 2471
#define OP_glUnmapBufferAsyncAEMU 2472
#define OP_glFlushMappedBufferRangeAEMU2 2473
-#define OP_last 2474
+#define OP_glBufferDataSyncAEMU 2474
+#define OP_last 2475
#endif
diff --git a/system/OpenglSystemCommon/EGLImage.h b/system/OpenglSystemCommon/EGLImage.h
index a83e1ad..8a1eb6d 100644
--- a/system/OpenglSystemCommon/EGLImage.h
+++ b/system/OpenglSystemCommon/EGLImage.h
@@ -36,6 +36,8 @@
{
EGLDisplay dpy;
EGLenum target;
+ int width;
+ int height;
union
{
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index f4467bb..f6d8ce5 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -125,6 +125,10 @@
// Queue submit with commands
static const char kVulkanQueueSubmitWithCommands[] = "ANDROID_EMU_vulkan_queue_submit_with_commands";
+//
+// Synchronized glBufferData call
+static const char kSyncBufferData[] = "ANDROID_EMU_sync_buffer_data";
+
// Batched descriptor set update
static const char kVulkanBatchedDescriptorSetUpdate[] = "ANDROID_EMU_vulkan_batched_descriptor_set_update";
@@ -154,7 +158,8 @@
hasHostSideTracing(false),
hasAsyncFrameCommands(false),
hasVulkanQueueSubmitWithCommands(false),
- hasVulkanBatchedDescriptorSetUpdate(false)
+ hasVulkanBatchedDescriptorSetUpdate(false),
+ hasSyncBufferData(false)
{ }
SyncImpl syncImpl;
@@ -179,6 +184,7 @@
bool hasAsyncFrameCommands;
bool hasVulkanQueueSubmitWithCommands;
bool hasVulkanBatchedDescriptorSetUpdate;
+ bool hasSyncBufferData;
};
enum HostConnectionType {
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 1ad93b8..7610efc 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -40,6 +40,7 @@
void setNoHostError(bool) { }
void setDrawCallFlushInterval(uint32_t) { }
void setHasAsyncUnmapBuffer(int) { }
+ void setHasSyncBufferData(int) { }
};
#else
#include "GLEncoder.h"
@@ -620,6 +621,7 @@
m_gl2Enc->setDrawCallFlushInterval(
getDrawCallFlushIntervalFromProperty());
m_gl2Enc->setHasAsyncUnmapBuffer(m_rcEnc->hasAsyncUnmapBuffer());
+ m_gl2Enc->setHasSyncBufferData(m_rcEnc->hasSyncBufferData());
}
return m_gl2Enc.get();
}
@@ -664,6 +666,8 @@
queryAndSetAsyncFrameCommands(rcEnc);
queryAndSetVulkanQueueSubmitWithCommandsSupport(rcEnc);
queryAndSetVulkanBatchedDescriptorSetUpdateSupport(rcEnc);
+ queryAndSetSyncBufferData(rcEnc);
+ queryVersion(rcEnc);
if (m_processPipe) {
m_processPipe->processPipeInit(m_connectionType, rcEnc);
}
@@ -954,3 +958,15 @@
rcEnc->featureInfo()->hasVulkanBatchedDescriptorSetUpdate = true;
}
}
+
+void HostConnection::queryAndSetSyncBufferData(ExtendedRCEncoderContext* rcEnc) {
+ std::string glExtensions = queryGLExtensions(rcEnc);
+ if (glExtensions.find(kSyncBufferData) != std::string::npos) {
+ rcEnc->featureInfo()->hasSyncBufferData = true;
+ }
+}
+
+GLint HostConnection::queryVersion(ExtendedRCEncoderContext* rcEnc) {
+ GLint version = m_rcEnc->rcGetRendererVersion(m_rcEnc.get());
+ return version;
+}
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index c1c3f40..7c55629 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -75,6 +75,8 @@
bool hasAsyncFrameCommands() const {
return m_featureInfo.hasAsyncFrameCommands;
}
+ bool hasSyncBufferData() const {
+ return m_featureInfo.hasSyncBufferData; }
DmaImpl getDmaVersion() const { return m_featureInfo.dmaImpl; }
void bindDmaContext(struct goldfish_dma_context* cxt) { m_dmaCxt = cxt; }
void bindDmaDirectly(void* dmaPtr, uint64_t dmaPhysAddr) {
@@ -239,6 +241,8 @@
void queryAndSetAsyncFrameCommands(ExtendedRCEncoderContext *rcEnc);
void queryAndSetVulkanQueueSubmitWithCommandsSupport(ExtendedRCEncoderContext *rcEnc);
void queryAndSetVulkanBatchedDescriptorSetUpdateSupport(ExtendedRCEncoderContext *rcEnc);
+ void queryAndSetSyncBufferData(ExtendedRCEncoderContext *rcEnc);
+ GLint queryVersion(ExtendedRCEncoderContext* rcEnc);
private:
HostConnectionType m_connectionType;
diff --git a/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
index 15b90d4..f445244 100644
--- a/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
+++ b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
@@ -304,14 +304,14 @@
zx_signals_t observed = ZX_SIGNAL_NONE;
zx_status_t status = m_event.wait_one(
- fuchsia_hardware_goldfish::wire::SIGNAL_READABLE |
- fuchsia_hardware_goldfish::wire::SIGNAL_HANGUP,
+ fuchsia_hardware_goldfish::wire::kSignalReadable |
+ fuchsia_hardware_goldfish::wire::kSignalHangup,
zx::time::infinite(), &observed);
if (status != ZX_OK) {
ALOGD("%s: wait_one failed: %d", __FUNCTION__, status);
return nullptr;
}
- if (observed & fuchsia_hardware_goldfish::wire::SIGNAL_HANGUP) {
+ if (observed & fuchsia_hardware_goldfish::wire::kSignalHangup) {
ALOGD("%s: Remote end hungup", __FUNCTION__);
return nullptr;
}
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
index 1a9368a..a65ce67 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
@@ -512,8 +512,6 @@
return true;
}
-bool C2GoldfishAvcDec::getVuiParams() { return true; }
-
status_t C2GoldfishAvcDec::setFlushMode() {
if (mContext) {
mContext->flush();
@@ -703,7 +701,41 @@
}
}
+void C2GoldfishAvcDec::getVuiParams(h264_image_t &img) {
+
+ VuiColorAspects vuiColorAspects;
+ vuiColorAspects.primaries = img.color_primaries;
+ vuiColorAspects.transfer = img.color_trc;
+ vuiColorAspects.coeffs = img.colorspace;
+ vuiColorAspects.fullRange = img.color_range == 2 ? true : false;
+
+ // convert vui aspects to C2 values if changed
+ if (!(vuiColorAspects == mBitstreamColorAspects)) {
+ mBitstreamColorAspects = vuiColorAspects;
+ ColorAspects sfAspects;
+ C2StreamColorAspectsInfo::input codedAspects = {0u};
+ ColorUtils::convertIsoColorAspectsToCodecAspects(
+ vuiColorAspects.primaries, vuiColorAspects.transfer,
+ vuiColorAspects.coeffs, vuiColorAspects.fullRange, sfAspects);
+ if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
+ codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
+ codedAspects.range = C2Color::RANGE_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
+ codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
+ codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
+ }
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
+ }
+}
+
void C2GoldfishAvcDec::copyImageData(uint8_t *pBuffer, h264_image_t &img) {
+ getVuiParams(img);
if (mEnableAndroidNativeBuffers)
return;
int myStride = mWidth;
@@ -843,7 +875,6 @@
// (void) ivdec_api_function(mDecHandle, &s_decode_ip,
// &s_decode_op);
}
- (void)getVuiParams();
if (mImg.data != nullptr) {
DDD("got data %" PRIu64, mPts2Index[mImg.pts]);
hasPicture = true;
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
index 57b1d69..f97b2b0 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
@@ -65,7 +65,6 @@
status_t initDecoder();
bool setDecodeArgs(C2ReadView *inBuffer, C2GraphicView *outBuffer,
size_t inOffset, size_t inSize, uint32_t tsMarker);
- bool getVuiParams();
c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
status_t setFlushMode();
@@ -98,6 +97,7 @@
int mHostColorBufferId{-1};
+ void getVuiParams(h264_image_t &img);
void copyImageData(uint8_t *pBuffer, h264_image_t &img);
uint8_t *mByteBuffer{nullptr};
diff --git a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
index b33ce2e..7df99ff 100644
--- a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
+++ b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
@@ -89,8 +89,8 @@
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
.withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
.withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
+ C2F(mSize, width).inRange(2, 4096, 2),
+ C2F(mSize, height).inRange(2, 4096, 2),
})
.withSetter(SizeSetter)
.build());
@@ -178,8 +178,8 @@
.withDefault(new C2StreamMaxPictureSizeTuning::output(
0u, 320, 240))
.withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
+ C2F(mSize, width).inRange(2, 4096, 2),
+ C2F(mSize, height).inRange(2, 4096, 2),
})
.withSetter(MaxPictureSizeSetter, mSize)
.build());
@@ -242,17 +242,25 @@
const C2P<C2StreamPictureSizeInfo::output> &oldMe,
C2P<C2StreamPictureSizeInfo::output> &me) {
(void)mayBlock;
- DDD("calling sizesetter now %d", oldMe.v.height);
- DDD("new calling sizesetter now %d", me.v.height);
+ DDD("calling sizesetter old w %d", oldMe.v.width);
+ DDD("calling sizesetter old h %d", oldMe.v.height);
+ DDD("calling sizesetter change to w %d", me.v.width);
+ DDD("calling sizesetter change to h %d", me.v.height);
C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+ auto mewidth = me.F(me.v.width);
+ auto meheight = me.F(me.v.height);
+
+ if (!mewidth.supportsAtAll(me.v.width)) {
res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+ DDD("override width with oldMe value");
me.set().width = oldMe.v.width;
+ DDD("something wrong here %s %d", __func__, __LINE__);
}
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+ if (!meheight.supportsAtAll(me.v.height)) {
res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- DDD("override with oldMe value");
+ DDD("override height with oldMe value");
me.set().height = oldMe.v.height;
+ DDD("something wrong here %s %d", __func__, __LINE__);
}
return res;
}
@@ -264,8 +272,8 @@
(void)mayBlock;
// TODO: get max width/height from the size's field helpers vs.
// hardcoding
- me.set().width = c2_min(c2_max(me.v.width, size.v.width), 2048u);
- me.set().height = c2_min(c2_max(me.v.height, size.v.height), 2048u);
+ me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4096u);
+ me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4096u);
return C2R::Ok();
}
diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp
index bfe0db6..c204899 100644
--- a/system/egl/egl.cpp
+++ b/system/egl/egl.cpp
@@ -1216,6 +1216,7 @@
}
int attribs_size = 0;
+ EGLint backup_attribs[1];
if (attrib_list) {
const EGLint * attrib_p = attrib_list;
while (attrib_p[0] != EGL_NONE) {
@@ -1223,6 +1224,10 @@
attrib_p += 2;
}
attribs_size++; //for the terminating EGL_NONE
+ } else {
+ attribs_size = 1;
+ backup_attribs[0] = EGL_NONE;
+ attrib_list = backup_attribs;
}
// API 19 passes EGL_SWAP_BEHAVIOR_PRESERVED_BIT to surface type,
@@ -2275,6 +2280,8 @@
image->dpy = dpy;
image->target = target;
image->native_buffer = native_buffer;
+ image->width = native_buffer->width;
+ image->height = native_buffer->width;
return (EGLImageKHR)image;
}
@@ -2291,6 +2298,8 @@
image->dpy = dpy;
image->target = target;
image->host_egl_image = img;
+ image->width = context->getClientState()->queryTexWidth(0, texture);
+ image->height = context->getClientState()->queryTexHeight(0, texture);
return (EGLImageKHR)image;
}
@@ -2376,17 +2385,17 @@
// Validate and input attribs
for (int i = 0; i < num_actual_attribs; i += 2) {
- if (attrib_list[i] == EGL_SYNC_TYPE_KHR) {
- DPRINT("ERROR: attrib key = EGL_SYNC_TYPE_KHR");
- }
- if (attrib_list[i] == EGL_SYNC_STATUS_KHR) {
- DPRINT("ERROR: attrib key = EGL_SYNC_STATUS_KHR");
- }
- if (attrib_list[i] == EGL_SYNC_CONDITION_KHR) {
- DPRINT("ERROR: attrib key = EGL_SYNC_CONDITION_KHR");
- }
EGLint attrib_key = attrib_list[i];
EGLint attrib_val = attrib_list[i + 1];
+ switch (attrib_key) {
+ case EGL_SYNC_TYPE_KHR:
+ case EGL_SYNC_STATUS_KHR:
+ case EGL_SYNC_CONDITION_KHR:
+ case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
+ break;
+ default:
+ setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+ }
if (attrib_key == EGL_SYNC_NATIVE_FENCE_FD_ANDROID) {
if (attrib_val != EGL_NO_NATIVE_FENCE_FD_ANDROID) {
inputFenceFd = attrib_val;
@@ -2455,8 +2464,8 @@
(void)dpy;
if (!eglsync) {
- DPRINT("WARNING: null sync object")
- return EGL_TRUE;
+ ALOGE("%s: null sync object!", __FUNCTION__);
+ setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
}
EGLSync_t* sync = static_cast<EGLSync_t*>(eglsync);
@@ -2487,8 +2496,8 @@
(void)dpy;
if (!eglsync) {
- DPRINT("WARNING: null sync object");
- return EGL_CONDITION_SATISFIED_KHR;
+ ALOGE("%s: null sync object!", __FUNCTION__);
+ setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
}
EGLSync_t* sync = (EGLSync_t*)eglsync;
@@ -2527,6 +2536,14 @@
EGLSync_t* sync = (EGLSync_t*)eglsync;
+ if (!sync) {
+ setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
+
+ if (!value) {
+ setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
+
switch (attribute) {
case EGL_SYNC_TYPE_KHR:
*value = sync->type;
@@ -2574,12 +2591,12 @@
if (!eglsync) {
ALOGE("%s: null sync object!", __FUNCTION__);
- return EGL_FALSE;
+ setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
}
if (flags) {
ALOGE("%s: flags must be 0, got 0x%x", __FUNCTION__, flags);
- return EGL_FALSE;
+ setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
}
DEFINE_HOST_CONNECTION;
diff --git a/system/hwc2/Android.mk b/system/hwc2/Android.mk
index 2254d2f..4d207ff 100644
--- a/system/hwc2/Android.mk
+++ b/system/hwc2/Android.mk
@@ -100,4 +100,7 @@
LOCAL_C_INCLUDES += external/drm_hwcomposer
LOCAL_C_INCLUDES += external/minigbm/cros_gralloc
LOCAL_MODULE := emulatorDrmTest
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../LICENSE
include $(BUILD_EXECUTABLE)
diff --git a/system/hwc2/Device.cpp b/system/hwc2/Device.cpp
index 3e32a50..24df956 100644
--- a/system/hwc2/Device.cpp
+++ b/system/hwc2/Device.cpp
@@ -525,7 +525,9 @@
}
if (connected) {
createDisplay(id, width, height, dpiX, dpiY, refreshRate);
- ALOGD("callback hotplugConnect display %" PRIu32, id);
+ ALOGD("callback hotplugConnect display %" PRIu32 " width %" PRIu32
+ " height %" PRIu32 " dpiX %" PRIu32 " dpiY %" PRIu32
+ "fps %" PRIu32, id, width, height, dpiX, dpiY, refreshRate);
hotplug(mCallbacks[HWC2::Callback::Hotplug].data, id, hotplugConnect);
};
diff --git a/system/hwc2/Display.cpp b/system/hwc2/Display.cpp
index 2faa947..99a7c01 100644
--- a/system/hwc2/Display.cpp
+++ b/system/hwc2/Display.cpp
@@ -69,10 +69,11 @@
Display::~Display() {}
HWC2::Error Display::init(uint32_t width, uint32_t height, uint32_t dpiX,
- uint32_t dpiY, uint32_t refreshRateHz) {
- DEBUG_LOG("%s initializing display:%" PRIu64
- " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
- __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);
+ uint32_t dpiY, uint32_t refreshRateHz,
+ const std::optional<std::vector<uint8_t>>& edid) {
+ ALOGD("%s initializing display:%" PRIu64
+ " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
+ __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);
std::unique_lock<std::recursive_mutex> lock(mStateMutex);
@@ -92,13 +93,15 @@
mActiveConfigId = configId;
mActiveColorMode = HAL_COLOR_MODE_NATIVE;
mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE);
+ mEdid = edid;
return HWC2::Error::None;
}
HWC2::Error Display::updateParameters(uint32_t width, uint32_t height,
uint32_t dpiX, uint32_t dpiY,
- uint32_t refreshRateHz) {
+ uint32_t refreshRateHz,
+ const std::optional<std::vector<uint8_t>>& edid) {
DEBUG_LOG("%s updating display:%" PRIu64
" width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
__FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);
@@ -118,6 +121,8 @@
it->second.setAttribute(HWC2::Attribute::DpiX, dpiX * 1000);
it->second.setAttribute(HWC2::Attribute::DpiY, dpiY * 1000);
+ mEdid = edid;
+
return HWC2::Error::None;
}
@@ -301,7 +306,7 @@
// we only support HAL_COLOR_MODE_NATIVE so far
uint32_t numModes =
- std::min(*outNumModes, static_cast<uint32_t>(mColorModes.size()));
+ std::min<uint32_t>(*outNumModes, static_cast<uint32_t>(mColorModes.size()));
std::copy_n(mColorModes.cbegin(), numModes, outModes);
*outNumModes = numModes;
return HWC2::Error::None;
@@ -760,6 +765,18 @@
return HWC2::Error::BadParameter;
}
+ if (mEdid) {
+ if (outData) {
+ *outDataSize = std::min<uint32_t>(*outDataSize, (*mEdid).size());
+ memcpy(outData, (*mEdid).data(), *outDataSize);
+ } else {
+ *outDataSize = (*mEdid).size();
+ }
+ *outPort = mId;
+ return HWC2::Error::None;
+ }
+
+ // fallback to legacy EDID implementation
uint32_t len = std::min(*outDataSize, (uint32_t)ARRAY_SIZE(sEDID0));
if (outData != nullptr && len < (uint32_t)ARRAY_SIZE(sEDID0)) {
ALOGW("%s: display:%" PRIu64 " small buffer size: %u is specified",
diff --git a/system/hwc2/Display.h b/system/hwc2/Display.h
index 277933a..418e26c 100644
--- a/system/hwc2/Display.h
+++ b/system/hwc2/Display.h
@@ -47,10 +47,13 @@
Display& operator=(Display&& display) = delete;
HWC2::Error init(uint32_t width, uint32_t height, uint32_t dpiX,
- uint32_t dpiY, uint32_t refreshRateHz);
+ uint32_t dpiY, uint32_t refreshRateHz,
+ const std::optional<std::vector<uint8_t>>& edid = std::nullopt);
HWC2::Error updateParameters(uint32_t width, uint32_t height, uint32_t dpiX,
- uint32_t dpiY, uint32_t refreshRateHz);
+ uint32_t dpiY, uint32_t refreshRateHz,
+ const std::optional<std::vector<uint8_t>>& edid
+ = std::nullopt);
hwc2_display_t getId() const { return mId; }
@@ -226,6 +229,7 @@
std::set<android_color_mode_t> mColorModes;
android_color_mode_t mActiveColorMode;
bool mSetColorTransform = false;
+ std::optional<std::vector<uint8_t>> mEdid;
};
} // namespace android
diff --git a/system/hwc2/DrmPresenter.cpp b/system/hwc2/DrmPresenter.cpp
index 22bd08c..4d63c58 100644
--- a/system/hwc2/DrmPresenter.cpp
+++ b/system/hwc2/DrmPresenter.cpp
@@ -222,6 +222,8 @@
mFd.get(), connectorProps->props[connectorPropIndex]);
if (!strcmp(connectorProp->name, "CRTC_ID")) {
connector.mCrtcPropertyId = connectorProp->prop_id;
+ } else if (!strcmp(connectorProp->name, "EDID")) {
+ connector.mEdidBlobId = connectorProps->prop_values[connectorPropIndex];
}
drmModeFreeProperty(connectorProp);
}
@@ -244,11 +246,11 @@
// Dots per 1000 inches
connector.dpiX =
- c->mmWidth ? (c->mmWidth * kUmPerInch * 10) / c->modes[0].hdisplay
+ c->mmWidth ? (c->modes[0].hdisplay * kUmPerInch) / (c->mmWidth)
: -1;
// Dots per 1000 inches
connector.dpiY =
- c->mmHeight ? (c->mmHeight * kUmPerInch * 10) / c->modes[0].vdisplay
+ c->mmHeight ? (c->modes[0].vdisplay * kUmPerInch) / (c->mmHeight)
: -1;
}
ALOGD("%s connector %" PRIu32 " dpiX %" PRIi32 " dpiY %" PRIi32
@@ -492,6 +494,29 @@
return error;
}
+std::optional<std::vector<uint8_t>> DrmPresenter::getEdid(uint32_t id) {
+ AutoReadLock lock(mStateMutex);
+
+ if (mConnectors[id].mEdidBlobId == -1) {
+ ALOGW("%s: EDID not supported", __func__);
+ return std::nullopt;
+ }
+ drmModePropertyBlobPtr blob = drmModeGetPropertyBlob(mFd.get(),
+ mConnectors[id].mEdidBlobId);
+ if (!blob) {
+ ALOGE("%s: fail to read EDID from DRM", __func__);
+ return std::nullopt;
+ }
+
+ std::vector<uint8_t> edid;
+ uint8_t* start = static_cast<uint8_t*>(blob->data);
+ edid.insert(edid.begin(), start, start + blob->length);
+
+ drmModeFreePropertyBlob(blob);
+
+ return edid;
+}
+
DrmBuffer::DrmBuffer(const native_handle_t* handle, DrmPresenter& DrmPresenter)
: mDrmPresenter(DrmPresenter), mBo({}) {
if (!convertBoInfo(handle)) {
diff --git a/system/hwc2/DrmPresenter.h b/system/hwc2/DrmPresenter.h
index 6fbb4c7..7f9edb2 100644
--- a/system/hwc2/DrmPresenter.h
+++ b/system/hwc2/DrmPresenter.h
@@ -78,6 +78,8 @@
HWC2::Error flushToDisplay(int display, hwc_drm_bo_t& fb, int* outSyncFd);
+ std::optional<std::vector<uint8_t>> getEdid(uint32_t id);
+
private:
// Grant visibility for getDrmFB and clearDrmFB to DrmBuffer.
friend class DrmBuffer;
@@ -136,6 +138,7 @@
uint32_t mModeBlobId = 0;
float mRefreshRateAsFloat;
uint32_t mRefreshRateAsInteger;
+ uint64_t mEdidBlobId = -1;
};
std::vector<DrmConnector> mConnectors;
diff --git a/system/hwc2/HostComposer.cpp b/system/hwc2/HostComposer.cpp
index a4ab183..c55eccd 100644
--- a/system/hwc2/HostComposer.cpp
+++ b/system/hwc2/HostComposer.cpp
@@ -152,7 +152,6 @@
const native_handle_t* AllocateDisplayColorBuffer(int width, int height) {
const uint32_t layerCount = 1;
const uint64_t graphicBufferId = 0; // not used
-
buffer_handle_t h;
uint32_t stride;
@@ -266,13 +265,17 @@
hostCon->unlock();
return HWC2::Error::NoResources;
}
- if (rcEnc->rcSetDisplayPose(rcEnc, displayId, -1, -1, width, height)) {
+ if (rcEnc->rcSetDisplayPoseDpi(rcEnc, displayId, -1, -1, width, height, dpiX/1000)) {
ALOGE("%s host failed to set display %" PRIu32, __func__, displayId);
hostCon->unlock();
return HWC2::Error::NoResources;
}
hostCon->unlock();
+ std::optional<std::vector<uint8_t>> edid;
+ if (mIsMinigbm) {
+ edid = mDrmPresenter.getEdid(displayId);
+ }
if (!display) {
auto newDisplay = std::make_unique<Display>(*device, this, displayId);
if (newDisplay == nullptr) {
@@ -280,7 +283,8 @@
return HWC2::Error::NoResources;
}
- error = newDisplay->init(width, height, dpiX, dpiY, refreshRateHz);
+
+ error = newDisplay->init(width, height, dpiX, dpiY, refreshRateHz, edid);
if (error != HWC2::Error::None) {
ALOGE("%s failed to initialize display:%" PRIu32, __FUNCTION__,
displayId);
@@ -303,7 +307,8 @@
} else {
display->lock();
// update display parameters
- error = display->updateParameters(width, height, dpiX, dpiY, refreshRateHz);
+ error = display->updateParameters(width, height, dpiX, dpiY,
+ refreshRateHz, edid);
if (error != HWC2::Error::None) {
ALOGE("%s failed to update display:%" PRIu32, __FUNCTION__, displayId);
display->unlock();
@@ -568,6 +573,7 @@
if (display->hasColorTransform()) {
fallBack = true;
}
+
if (fallBack) {
for (auto& layer : layers) {
if (layer->getCompositionType() == HWC2::Composition::Invalid) {
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index c160259..21780a8 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -338,7 +338,7 @@
};
struct VkQueue_Info {
- uint32_t placeholder;
+ VkDevice device;
};
// custom guest-side structs for images/buffers because of AHardwareBuffer :((
@@ -419,6 +419,10 @@
uint32_t unused;
};
+ struct VkSampler_Info {
+ uint32_t unused;
+ };
+
struct VkBufferCollectionFUCHSIA_Info {
#ifdef VK_USE_PLATFORM_FUCHSIA
android::base::Optional<
@@ -478,6 +482,13 @@
info_VkCommandPool.erase(pool);
}
+ void unregister_VkSampler(VkSampler sampler) {
+ if (!sampler) return;
+
+ AutoLock lock(mLock);
+ info_VkSampler.erase(sampler);
+ }
+
void unregister_VkCommandBuffer(VkCommandBuffer commandBuffer) {
resetCommandBufferStagingInfo(commandBuffer, true /* also reset primaries */, true /* also clear pending descriptor sets */);
@@ -709,34 +720,32 @@
return res;
}
- VkWriteDescriptorSet
- createImmutableSamplersFilteredWriteDescriptorSetLocked(
- const VkWriteDescriptorSet* descriptorWrite,
- std::vector<VkDescriptorImageInfo>* imageInfoArray) {
+ bool descriptorBindingIsImmutableSampler(
+ VkDescriptorSet dstSet,
+ uint32_t dstBinding) {
- VkWriteDescriptorSet res = *descriptorWrite;
+ return as_goldfish_VkDescriptorSet(dstSet)->reified->bindingIsImmutableSampler[dstBinding];
+ }
- if (descriptorWrite->descriptorCount == 0) return res;
+ VkDescriptorImageInfo
+ filterNonexistentSampler(
+ const VkDescriptorImageInfo& inputInfo) {
- if (descriptorWrite->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER &&
- descriptorWrite->descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) return res;
+ VkSampler sampler =
+ inputInfo.sampler;
- bool immutableSampler =
- as_goldfish_VkDescriptorSet(descriptorWrite->dstSet)->reified->bindingIsImmutableSampler[descriptorWrite->dstBinding];
+ VkDescriptorImageInfo res = inputInfo;
- if (!immutableSampler) return res;
-
- for (uint32_t i = 0; i < descriptorWrite->descriptorCount; ++i) {
- VkDescriptorImageInfo imageInfo = descriptorWrite->pImageInfo[i];
- imageInfo.sampler = 0;
- imageInfoArray->push_back(imageInfo);
+ if (sampler) {
+ auto it = info_VkSampler.find(sampler);
+ bool samplerExists = it != info_VkSampler.end();
+ if (!samplerExists) res.sampler = 0;
}
- res.pImageInfo = imageInfoArray->data();
-
return res;
}
+
void freeDescriptorSetsIfHostAllocated(VkEncoder* enc, VkDevice device, uint32_t descriptorSetCount, const VkDescriptorSet* sets) {
for (uint32_t i = 0; i < descriptorSetCount; ++i) {
struct goldfish_VkDescriptorSet* ds = as_goldfish_VkDescriptorSet(sets[i]);
@@ -1578,6 +1587,23 @@
}
}
+ void on_vkGetDeviceQueue(void*,
+ VkDevice device,
+ uint32_t,
+ uint32_t,
+ VkQueue* pQueue) {
+ AutoLock lock(mLock);
+ info_VkQueue[*pQueue].device = device;
+ }
+
+ void on_vkGetDeviceQueue2(void*,
+ VkDevice device,
+ const VkDeviceQueueInfo2*,
+ VkQueue* pQueue) {
+ AutoLock lock(mLock);
+ info_VkQueue[*pQueue].device = device;
+ }
+
VkResult on_vkCreateInstance(
void* context,
VkResult input_result,
@@ -1742,8 +1768,8 @@
VkExternalMemoryHandleTypeFlagBits handleType,
uint32_t handle,
VkMemoryZirconHandlePropertiesFUCHSIA* pProperties) {
- using fuchsia_hardware_goldfish::wire::MEMORY_PROPERTY_DEVICE_LOCAL;
- using fuchsia_hardware_goldfish::wire::MEMORY_PROPERTY_HOST_VISIBLE;
+ using fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal;
+ using fuchsia_hardware_goldfish::wire::kMemoryPropertyHostVisible;
if (handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA &&
handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA) {
@@ -1791,7 +1817,7 @@
// If an VMO is allocated while ColorBuffer/Buffer is not created,
// it must be a device-local buffer, since for host-visible buffers,
// ColorBuffer/Buffer is created at sysmem allocation time.
- memoryProperty = MEMORY_PROPERTY_DEVICE_LOCAL;
+ memoryProperty = kMemoryPropertyDeviceLocal;
} else {
// Importing read-only host memory into the Vulkan driver should not
// work, but it is not an error to try to do so. Returning a
@@ -1805,10 +1831,10 @@
pProperties->memoryTypeBits = 0;
for (uint32_t i = 0; i < info.memProps.memoryTypeCount; ++i) {
- if (((memoryProperty & MEMORY_PROPERTY_DEVICE_LOCAL) &&
+ if (((memoryProperty & kMemoryPropertyDeviceLocal) &&
(info.memProps.memoryTypes[i].propertyFlags &
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) ||
- ((memoryProperty & MEMORY_PROPERTY_HOST_VISIBLE) &&
+ ((memoryProperty & kMemoryPropertyHostVisible) &&
(info.memProps.memoryTypes[i].propertyFlags &
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
pProperties->memoryTypeBits |= 1ull << i;
@@ -2002,9 +2028,9 @@
buffer_constraints.inaccessible_domain_supported = true;
buffer_constraints.heap_permitted_count = 2;
buffer_constraints.heap_permitted[0] =
- fuchsia_sysmem::wire::HeapType::GOLDFISH_DEVICE_LOCAL;
+ fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal;
buffer_constraints.heap_permitted[1] =
- fuchsia_sysmem::wire::HeapType::GOLDFISH_HOST_VISIBLE;
+ fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
return constraints;
}
@@ -2014,15 +2040,15 @@
uint32_t usage = 0u;
VkImageUsageFlags imageUsage = pImageInfo->usage;
-#define SetUsageBit(USAGE) \
- if (imageUsage & VK_IMAGE_USAGE_##USAGE##_BIT) { \
- usage |= fuchsia_sysmem::wire::VULKAN_IMAGE_USAGE_##USAGE; \
+#define SetUsageBit(BIT, VALUE) \
+ if (imageUsage & VK_IMAGE_USAGE_##BIT##_BIT) { \
+ usage |= fuchsia_sysmem::wire::kVulkanImageUsage##VALUE; \
}
- SetUsageBit(COLOR_ATTACHMENT);
- SetUsageBit(TRANSFER_SRC);
- SetUsageBit(TRANSFER_DST);
- SetUsageBit(SAMPLED);
+ SetUsageBit(COLOR_ATTACHMENT, ColorAttachment);
+ SetUsageBit(TRANSFER_SRC, TransferSrc);
+ SetUsageBit(TRANSFER_DST, TransferDst);
+ SetUsageBit(SAMPLED, Sampled);
#undef SetUsageBit
return usage;
@@ -2034,20 +2060,20 @@
VkBufferUsageFlags bufferUsage =
pBufferConstraintsInfo->pBufferCreateInfo->usage;
-#define SetUsageBit(USAGE) \
- if (bufferUsage & VK_BUFFER_USAGE_##USAGE##_BIT) { \
- usage |= fuchsia_sysmem::wire::VULKAN_BUFFER_USAGE_##USAGE; \
+#define SetUsageBit(BIT, VALUE) \
+ if (bufferUsage & VK_BUFFER_USAGE_##BIT##_BIT) { \
+ usage |= fuchsia_sysmem::wire::kVulkanBufferUsage##VALUE; \
}
- SetUsageBit(TRANSFER_SRC);
- SetUsageBit(TRANSFER_DST);
- SetUsageBit(UNIFORM_TEXEL_BUFFER);
- SetUsageBit(STORAGE_TEXEL_BUFFER);
- SetUsageBit(UNIFORM_BUFFER);
- SetUsageBit(STORAGE_BUFFER);
- SetUsageBit(INDEX_BUFFER);
- SetUsageBit(VERTEX_BUFFER);
- SetUsageBit(INDIRECT_BUFFER);
+ SetUsageBit(TRANSFER_SRC, TransferSrc);
+ SetUsageBit(TRANSFER_DST, TransferDst);
+ SetUsageBit(UNIFORM_TEXEL_BUFFER, UniformTexelBuffer);
+ SetUsageBit(STORAGE_TEXEL_BUFFER, StorageTexelBuffer);
+ SetUsageBit(UNIFORM_BUFFER, UniformBuffer);
+ SetUsageBit(STORAGE_BUFFER, StorageBuffer);
+ SetUsageBit(INDEX_BUFFER, IndexBuffer);
+ SetUsageBit(VERTEX_BUFFER, VertexBuffer);
+ SetUsageBit(INDIRECT_BUFFER, IndirectBuffer);
#undef SetUsageBit
return usage;
@@ -2062,14 +2088,14 @@
case VK_FORMAT_B8G8R8A8_SNORM:
case VK_FORMAT_B8G8R8A8_SSCALED:
case VK_FORMAT_B8G8R8A8_USCALED:
- return fuchsia_sysmem::wire::PixelFormatType::BGRA32;
+ return fuchsia_sysmem::wire::PixelFormatType::kBgra32;
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SRGB:
case VK_FORMAT_R8G8B8A8_SNORM:
case VK_FORMAT_R8G8B8A8_SSCALED:
case VK_FORMAT_R8G8B8A8_USCALED:
- return fuchsia_sysmem::wire::PixelFormatType::R8G8B8A8;
+ return fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8;
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_USCALED:
@@ -2077,7 +2103,7 @@
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8_SSCALED:
case VK_FORMAT_R8_SRGB:
- return fuchsia_sysmem::wire::PixelFormatType::R8;
+ return fuchsia_sysmem::wire::PixelFormatType::kR8;
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8_USCALED:
@@ -2085,9 +2111,9 @@
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R8G8_SSCALED:
case VK_FORMAT_R8G8_SRGB:
- return fuchsia_sysmem::wire::PixelFormatType::R8G8;
+ return fuchsia_sysmem::wire::PixelFormatType::kR8G8;
default:
- return fuchsia_sysmem::wire::PixelFormatType::INVALID;
+ return fuchsia_sysmem::wire::PixelFormatType::kInvalid;
}
}
@@ -2102,7 +2128,7 @@
case VK_FORMAT_B8G8R8A8_SSCALED:
case VK_FORMAT_B8G8R8A8_USCALED:
return sysmemFormat ==
- fuchsia_sysmem::wire::PixelFormatType::BGRA32;
+ fuchsia_sysmem::wire::PixelFormatType::kBgra32;
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SRGB:
@@ -2110,7 +2136,7 @@
case VK_FORMAT_R8G8B8A8_SSCALED:
case VK_FORMAT_R8G8B8A8_USCALED:
return sysmemFormat ==
- fuchsia_sysmem::wire::PixelFormatType::R8G8B8A8;
+ fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8;
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_USCALED:
@@ -2119,9 +2145,9 @@
case VK_FORMAT_R8_SSCALED:
case VK_FORMAT_R8_SRGB:
return sysmemFormat ==
- fuchsia_sysmem::wire::PixelFormatType::R8 ||
+ fuchsia_sysmem::wire::PixelFormatType::kR8 ||
sysmemFormat ==
- fuchsia_sysmem::wire::PixelFormatType::L8;
+ fuchsia_sysmem::wire::PixelFormatType::kL8;
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8_USCALED:
@@ -2130,7 +2156,7 @@
case VK_FORMAT_R8G8_SSCALED:
case VK_FORMAT_R8G8_SRGB:
return sysmemFormat ==
- fuchsia_sysmem::wire::PixelFormatType::R8G8;
+ fuchsia_sysmem::wire::PixelFormatType::kR8G8;
default:
return false;
}
@@ -2139,14 +2165,14 @@
static VkFormat sysmemPixelFormatTypeToVk(
fuchsia_sysmem::wire::PixelFormatType format) {
switch (format) {
- case fuchsia_sysmem::wire::PixelFormatType::BGRA32:
+ case fuchsia_sysmem::wire::PixelFormatType::kBgra32:
return VK_FORMAT_B8G8R8A8_SRGB;
- case fuchsia_sysmem::wire::PixelFormatType::R8G8B8A8:
+ case fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8:
return VK_FORMAT_R8G8B8A8_SRGB;
- case fuchsia_sysmem::wire::PixelFormatType::L8:
- case fuchsia_sysmem::wire::PixelFormatType::R8:
+ case fuchsia_sysmem::wire::PixelFormatType::kL8:
+ case fuchsia_sysmem::wire::PixelFormatType::kR8:
return VK_FORMAT_R8_UNORM;
- case fuchsia_sysmem::wire::PixelFormatType::R8G8:
+ case fuchsia_sysmem::wire::PixelFormatType::kR8G8:
return VK_FORMAT_R8G8_UNORM;
default:
return VK_FORMAT_UNDEFINED;
@@ -2265,7 +2291,7 @@
} else {
auto pixel_format = vkFormatTypeToSysmem(createInfo->format);
if (pixel_format ==
- fuchsia_sysmem::wire::PixelFormatType::INVALID) {
+ fuchsia_sysmem::wire::PixelFormatType::kInvalid) {
ALOGW("%s: Unsupported VkFormat %u", __func__,
static_cast<uint32_t>(createInfo->format));
return VK_ERROR_FORMAT_NOT_SUPPORTED;
@@ -2276,7 +2302,7 @@
if (!formatConstraints || formatConstraints->colorSpaceCount == 0u) {
imageConstraints.color_spaces_count = 1;
imageConstraints.color_space[0].type =
- fuchsia_sysmem::wire::ColorSpaceType::SRGB;
+ fuchsia_sysmem::wire::ColorSpaceType::kSrgb;
} else {
imageConstraints.color_spaces_count =
formatConstraints->colorSpaceCount;
@@ -2318,9 +2344,8 @@
imageConstraints.pixel_format.has_format_modifier = true;
imageConstraints.pixel_format.format_modifier.value =
(tiling == VK_IMAGE_TILING_LINEAR)
- ? fuchsia_sysmem::wire::FORMAT_MODIFIER_LINEAR
- : fuchsia_sysmem::wire::
- FORMAT_MODIFIER_GOOGLE_GOLDFISH_OPTIMAL;
+ ? fuchsia_sysmem::wire::kFormatModifierLinear
+ : fuchsia_sysmem::wire::kFormatModifierGoogleGoldfishOptimal;
constraints->image_format_constraints
[constraints->image_format_constraints_count++] =
@@ -2416,13 +2441,13 @@
// and flags.
VkImageConstraintsInfoFlagsFUCHSIA flags = pImageConstraintsInfo->flags;
if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA)
- constraints.usage.cpu |= fuchsia_sysmem::wire::cpuUsageRead;
+ constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageRead;
if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA)
- constraints.usage.cpu |= fuchsia_sysmem::wire::cpuUsageReadOften;
+ constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageReadOften;
if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA)
- constraints.usage.cpu |= fuchsia_sysmem::wire::cpuUsageWrite;
+ constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageWrite;
if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA)
- constraints.usage.cpu |= fuchsia_sysmem::wire::cpuUsageWriteOften;
+ constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageWriteOften;
constraints.has_buffer_memory_constraints = true;
auto& memory_constraints = constraints.buffer_memory_constraints;
@@ -2438,13 +2463,13 @@
if (memory_constraints.inaccessible_domain_supported) {
memory_constraints.heap_permitted_count = 2;
memory_constraints.heap_permitted[0] =
- fuchsia_sysmem::wire::HeapType::GOLDFISH_DEVICE_LOCAL;
+ fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal;
memory_constraints.heap_permitted[1] =
- fuchsia_sysmem::wire::HeapType::GOLDFISH_HOST_VISIBLE;
+ fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
} else {
memory_constraints.heap_permitted_count = 1;
memory_constraints.heap_permitted[0] =
- fuchsia_sysmem::wire::HeapType::GOLDFISH_HOST_VISIBLE;
+ fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
}
if (constraints.image_format_constraints_count == 0) {
@@ -2580,7 +2605,7 @@
VkResult getBufferCollectionImageCreateInfoIndexLocked(
VkBufferCollectionFUCHSIA collection,
- fuchsia_sysmem::wire::BufferCollectionInfo_2& info,
+ fuchsia_sysmem::wire::BufferCollectionInfo2& info,
uint32_t* outCreateInfoIndex) {
if (!info_VkBufferCollectionFUCHSIA[collection]
.constraints.hasValue()) {
@@ -2665,13 +2690,13 @@
GET_STATUS_SAFE(result, status));
return VK_ERROR_INITIALIZATION_FAILED;
}
- fuchsia_sysmem::wire::BufferCollectionInfo_2 info =
+ fuchsia_sysmem::wire::BufferCollectionInfo2 info =
std::move(result.Unwrap()->buffer_collection_info);
bool is_host_visible = info.settings.buffer_settings.heap ==
- fuchsia_sysmem::wire::HeapType::GOLDFISH_HOST_VISIBLE;
+ fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
bool is_device_local = info.settings.buffer_settings.heap ==
- fuchsia_sysmem::wire::HeapType::GOLDFISH_DEVICE_LOCAL;
+ fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal;
if (!is_host_visible && !is_device_local) {
ALOGE("buffer collection uses a non-goldfish heap (type 0x%lu)",
static_cast<uint64_t>(info.settings.buffer_settings.heap));
@@ -3189,7 +3214,7 @@
GET_STATUS_SAFE(result, status));
return VK_ERROR_INITIALIZATION_FAILED;
}
- fuchsia_sysmem::wire::BufferCollectionInfo_2& info =
+ fuchsia_sysmem::wire::BufferCollectionInfo2& info =
result.Unwrap()->buffer_collection_info;
uint32_t index = importBufferCollectionInfoPtr->index;
if (info.buffer_count < index) {
@@ -3328,7 +3353,7 @@
{
auto result = collection.WaitForBuffersAllocated();
if (result.ok() && result.Unwrap()->status == ZX_OK) {
- fuchsia_sysmem::wire::BufferCollectionInfo_2& info =
+ fuchsia_sysmem::wire::BufferCollectionInfo2& info =
result.Unwrap()->buffer_collection_info;
if (!info.buffer_count) {
ALOGE(
@@ -3374,7 +3399,7 @@
case VK_FORMAT_B8G8R8A8_SSCALED:
case VK_FORMAT_B8G8R8A8_USCALED:
format = fuchsia_hardware_goldfish::wire::
- ColorBufferFormatType::BGRA;
+ ColorBufferFormatType::kBgra;
break;
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_R8G8B8A8_UNORM:
@@ -3383,7 +3408,7 @@
case VK_FORMAT_R8G8B8A8_SSCALED:
case VK_FORMAT_R8G8B8A8_USCALED:
format = fuchsia_hardware_goldfish::wire::
- ColorBufferFormatType::RGBA;
+ ColorBufferFormatType::kRgba;
break;
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_UINT:
@@ -3393,7 +3418,7 @@
case VK_FORMAT_R8_SSCALED:
case VK_FORMAT_R8_SRGB:
format = fuchsia_hardware_goldfish::wire::
- ColorBufferFormatType::LUMINANCE;
+ ColorBufferFormatType::kLuminance;
break;
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8_UINT:
@@ -3403,7 +3428,7 @@
case VK_FORMAT_R8G8_SSCALED:
case VK_FORMAT_R8G8_SRGB:
format = fuchsia_hardware_goldfish::wire::
- ColorBufferFormatType::RG;
+ ColorBufferFormatType::kRg;
break;
default:
ALOGE("Unsupported format: %d",
@@ -3418,7 +3443,7 @@
.set_height(allocator, pImageCreateInfo->extent.height)
.set_format(allocator, format)
.set_memory_property(allocator,
- fuchsia_hardware_goldfish::wire::MEMORY_PROPERTY_DEVICE_LOCAL);
+ fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal);
auto result = mControlDevice->CreateColorBuffer2(
std::move(vmo_copy), std::move(createParams));
@@ -3444,7 +3469,7 @@
createParams.set_size(allocator,
pBufferConstraintsInfo->pBufferCreateInfo->size)
.set_memory_property(allocator,
- fuchsia_hardware_goldfish::wire::MEMORY_PROPERTY_DEVICE_LOCAL);
+ fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal);
auto result =
mControlDevice->CreateBuffer2(std::move(vmo_copy), std::move(createParams));
@@ -3478,7 +3503,7 @@
uint32_t buffer_handle = result.Unwrap()->id;
if (handle_type == fuchsia_hardware_goldfish::wire::
- BufferHandleType::BUFFER) {
+ BufferHandleType::kBuffer) {
importBufferInfo.buffer = buffer_handle;
vk_append_struct(&structChainIter, &importBufferInfo);
} else {
@@ -3922,7 +3947,7 @@
uint32_t index = extBufferCollectionPtr->index;
zx::vmo vmo;
- fuchsia_sysmem::wire::BufferCollectionInfo_2 info;
+ fuchsia_sysmem::wire::BufferCollectionInfo2 info;
auto result = collection->WaitForBuffersAllocated();
if (result.ok() && result.Unwrap()->status == ZX_OK) {
@@ -3953,7 +3978,7 @@
// Buffer handle already exists.
// If it is a ColorBuffer, no-op; Otherwise return error.
if (buffer_handle_result.value().type !=
- fuchsia_hardware_goldfish::wire::BufferHandleType::COLOR_BUFFER) {
+ fuchsia_hardware_goldfish::wire::BufferHandleType::kColorBuffer) {
ALOGE("%s: BufferHandle %u is not a ColorBuffer", __func__,
buffer_handle_result.value().id);
return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -3962,15 +3987,15 @@
// Buffer handle not found. Create ColorBuffer based on buffer settings.
auto format =
info.settings.image_format_constraints.pixel_format.type ==
- fuchsia_sysmem::wire::PixelFormatType::R8G8B8A8
- ? fuchsia_hardware_goldfish::wire::ColorBufferFormatType::RGBA
- : fuchsia_hardware_goldfish::wire::ColorBufferFormatType::BGRA;
+ fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8
+ ? fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kRgba
+ : fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kBgra;
uint32_t memory_property =
info.settings.buffer_settings.heap ==
- fuchsia_sysmem::wire::HeapType::GOLDFISH_DEVICE_LOCAL
- ? fuchsia_hardware_goldfish::wire::MEMORY_PROPERTY_DEVICE_LOCAL
- : fuchsia_hardware_goldfish::wire::MEMORY_PROPERTY_HOST_VISIBLE;
+ fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal
+ ? fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal
+ : fuchsia_hardware_goldfish::wire::kMemoryPropertyHostVisible;
fidl::FidlAllocator allocator;
fuchsia_hardware_goldfish::wire::CreateColorBuffer2Params createParams(
@@ -3991,7 +4016,7 @@
}
if (info.settings.buffer_settings.heap ==
- fuchsia_sysmem::wire::HeapType::GOLDFISH_HOST_VISIBLE) {
+ fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible) {
ALOGD(
"%s: Image uses host visible memory heap; set tiling "
"to linear to match host ImageCreateInfo",
@@ -4782,25 +4807,62 @@
VkEncoder* enc = (VkEncoder*)context;
- std::vector<std::vector<VkDescriptorImageInfo>> imageInfosPerWrite(
- descriptorWriteCount);
+ std::vector<VkDescriptorImageInfo> transformedImageInfos;
+ std::vector<VkWriteDescriptorSet> transformedWrites(descriptorWriteCount);
- std::vector<VkWriteDescriptorSet> writesWithSuppressedSamplers;
+ memcpy(transformedWrites.data(), pDescriptorWrites, sizeof(VkWriteDescriptorSet) * descriptorWriteCount);
+
+ size_t imageInfosNeeded = 0;
+ for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
+ if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
+ if (!transformedWrites[i].pImageInfo) continue;
+
+ imageInfosNeeded += transformedWrites[i].descriptorCount;
+ }
+
+ transformedImageInfos.resize(imageInfosNeeded);
+
+ size_t imageInfoIndex = 0;
+ for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
+ if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
+ if (!transformedWrites[i].pImageInfo) continue;
+
+ for (uint32_t j = 0; j < transformedWrites[i].descriptorCount; ++j) {
+ transformedImageInfos[imageInfoIndex] = transformedWrites[i].pImageInfo[j];
+ ++imageInfoIndex;
+ }
+ transformedWrites[i].pImageInfo = &transformedImageInfos[imageInfoIndex - transformedWrites[i].descriptorCount];
+ }
{
+ // Validate and filter samplers
AutoLock lock(mLock);
+ size_t imageInfoIndex = 0;
for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
- writesWithSuppressedSamplers.push_back(
- createImmutableSamplersFilteredWriteDescriptorSetLocked(
- pDescriptorWrites + i,
- imageInfosPerWrite.data() + i));
+
+ if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
+ if (!transformedWrites[i].pImageInfo) continue;
+
+ bool isImmutableSampler =
+ descriptorBindingIsImmutableSampler(
+ transformedWrites[i].dstSet,
+ transformedWrites[i].dstBinding);
+
+ for (uint32_t j = 0; j < transformedWrites[i].descriptorCount; ++j) {
+ if (isImmutableSampler) {
+ transformedImageInfos[imageInfoIndex].sampler = 0;
+ }
+ transformedImageInfos[imageInfoIndex] =
+ filterNonexistentSampler(transformedImageInfos[imageInfoIndex]);
+ ++imageInfoIndex;
+ }
}
}
if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate) {
for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
- VkDescriptorSet set = writesWithSuppressedSamplers[i].dstSet;
- doEmulatedDescriptorWrite(&writesWithSuppressedSamplers[i],
+ VkDescriptorSet set = transformedWrites[i].dstSet;
+ doEmulatedDescriptorWrite(&transformedWrites[i],
as_goldfish_VkDescriptorSet(set)->reified);
}
@@ -4811,7 +4873,7 @@
}
} else {
enc->vkUpdateDescriptorSets(
- device, descriptorWriteCount, writesWithSuppressedSamplers.data(),
+ device, descriptorWriteCount, transformedWrites.data(),
descriptorCopyCount, pDescriptorCopies, true /* do lock */);
}
}
@@ -4963,7 +5025,7 @@
fuchsia_hardware_goldfish::wire::CreateBuffer2Params createParams(allocator);
createParams.set_size(allocator, pCreateInfo->size)
.set_memory_property(allocator,
- fuchsia_hardware_goldfish::wire::MEMORY_PROPERTY_DEVICE_LOCAL);
+ fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal);
auto result =
mControlDevice->CreateBuffer2(std::move(*vmo), std::move(createParams));
@@ -5137,6 +5199,10 @@
if (exportEvent) {
finalCreateInfo.pNext = nullptr;
+ // If we have timeline semaphores externally, leave it there.
+ const VkSemaphoreTypeCreateInfo* typeCi =
+ vk_find_struct<VkSemaphoreTypeCreateInfo>(pCreateInfo);
+ if (typeCi) finalCreateInfo.pNext = typeCi;
}
#endif
@@ -5147,6 +5213,10 @@
if (exportSyncFd) {
finalCreateInfo.pNext = nullptr;
+ // If we have timeline semaphores externally, leave it there.
+ const VkSemaphoreTypeCreateInfo* typeCi =
+ vk_find_struct<VkSemaphoreTypeCreateInfo>(pCreateInfo);
+ if (typeCi) finalCreateInfo.pNext = typeCi;
}
#endif
input_result = enc->vkCreateSemaphore(
@@ -6440,6 +6510,14 @@
struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
cb->flags = pBeginInfo->flags;
+ VkCommandBufferBeginInfo modifiedBeginInfo;
+
+ if (pBeginInfo->pInheritanceInfo && !cb->isSecondary) {
+ modifiedBeginInfo = *pBeginInfo;
+ modifiedBeginInfo.pInheritanceInfo = nullptr;
+ pBeginInfo = &modifiedBeginInfo;
+ }
+
if (!supportsDeferredCommands()) {
return enc->vkBeginCommandBuffer(commandBuffer, pBeginInfo, true /* do lock */);
}
@@ -6601,6 +6679,27 @@
decDescriptorSetLayoutRef(context, device, descriptorSetLayout, pAllocator);
}
+ VkResult on_vkAllocateCommandBuffers(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers) {
+
+ (void)input_result;
+
+ VkEncoder* enc = (VkEncoder*)context;
+ VkResult res = enc->vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, true /* do lock */);
+ if (VK_SUCCESS != res) return res;
+
+ for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; ++i) {
+ struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(pCommandBuffers[i]);
+ cb->isSecondary = pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY;
+ }
+
+ return res;
+ }
+
uint32_t getApiVersionFromInstance(VkInstance instance) const {
AutoLock lock(mLock);
uint32_t api = kDefaultApiVersion;
@@ -6970,6 +7069,22 @@
context, physicalDevice, pMemoryProperties);
}
+void ResourceTracker::on_vkGetDeviceQueue(void* context,
+ VkDevice device,
+ uint32_t queueFamilyIndex,
+ uint32_t queueIndex,
+ VkQueue* pQueue) {
+ mImpl->on_vkGetDeviceQueue(context, device, queueFamilyIndex, queueIndex,
+ pQueue);
+}
+
+void ResourceTracker::on_vkGetDeviceQueue2(void* context,
+ VkDevice device,
+ const VkDeviceQueueInfo2* pQueueInfo,
+ VkQueue* pQueue) {
+ mImpl->on_vkGetDeviceQueue2(context, device, pQueueInfo, pQueue);
+}
+
VkResult ResourceTracker::on_vkCreateInstance(
void* context,
VkResult input_result,
@@ -7717,6 +7832,15 @@
mImpl->on_vkDestroyDescriptorSetLayout(context, device, descriptorSetLayout, pAllocator);
}
+VkResult ResourceTracker::on_vkAllocateCommandBuffers(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers) {
+ return mImpl->on_vkAllocateCommandBuffers(context, input_result, device, pAllocateInfo, pCommandBuffers);
+}
+
void ResourceTracker::deviceMemoryTransform_tohost(
VkDeviceMemory* memory, uint32_t memoryCount,
VkDeviceSize* offset, uint32_t offsetCount,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index cd5aa13..86e4dde 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -107,6 +107,15 @@
void* context,
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
+ void on_vkGetDeviceQueue(void* context,
+ VkDevice device,
+ uint32_t queueFamilyIndex,
+ uint32_t queueIndex,
+ VkQueue* pQueue);
+ void on_vkGetDeviceQueue2(void* context,
+ VkDevice device,
+ const VkDeviceQueueInfo2* pQueueInfo,
+ VkQueue* pQueue);
VkResult on_vkCreateInstance(
void* context,
@@ -559,6 +568,13 @@
VkDescriptorSetLayout descriptorSetLayout,
const VkAllocationCallbacks* pAllocator);
+ VkResult on_vkAllocateCommandBuffers(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers);
+
bool isMemoryTypeHostVisible(VkDevice device, uint32_t typeIndex) const;
uint8_t* getMappedPointer(VkDeviceMemory memory);
VkDeviceSize getMappedSize(VkDeviceMemory memory);
diff --git a/system/vulkan_enc/Resources.h b/system/vulkan_enc/Resources.h
index 74f41ee..67c498e 100644
--- a/system/vulkan_enc/Resources.h
+++ b/system/vulkan_enc/Resources.h
@@ -83,7 +83,7 @@
#define GOLDFISH_VK_GET_HOST_U64_DECL(type) \
uint64_t get_host_u64_##type(type);
-GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DEFINE_DISPATCHABLE_HANDLE_STRUCT)
+GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DEFINE_DISPATCHABLE_HANDLE_STRUCT)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_FROM_HOST_DECL)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_DECL)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_DECL)
@@ -116,6 +116,21 @@
goldfish_vk::DescriptorSetLayoutInfo* layoutInfo;
};
+struct goldfish_VkCommandBuffer {
+ hwvulkan_dispatch_t dispatch;
+ uint64_t underlying;
+ goldfish_vk::VkEncoder* lastUsedEncoder;
+ uint32_t sequenceNumber;
+ goldfish_vk::VkEncoder* privateEncoder;
+ IOStream* privateStream;
+ uint32_t flags;
+ struct goldfish_vk_object_list* poolObjects;
+ struct goldfish_vk_object_list* subObjects;
+ struct goldfish_vk_object_list* superObjects;
+ void* userPtr;
+ bool isSecondary;
+};
+
} // extern "C"
namespace goldfish_vk {
diff --git a/system/vulkan_enc/VkEncoder.cpp b/system/vulkan_enc/VkEncoder.cpp
index 27564ca..5660460 100644
--- a/system/vulkan_enc/VkEncoder.cpp
+++ b/system/vulkan_enc/VkEncoder.cpp
@@ -1629,6 +1629,8 @@
stream->read((uint64_t*)&cgen_var_2, 8);
stream->handleMapping()->mapHandles_u64_VkQueue(&cgen_var_2, (VkQueue*)pQueue, 1);
stream->unsetHandleMapping();
+ sResourceTracker->on_vkGetDeviceQueue(this, device, queueFamilyIndex,
+ queueIndex, pQueue);
++encodeCount;;
if (0 == encodeCount % POOL_CLEAR_INTERVAL)
{
@@ -12209,6 +12211,7 @@
uint64_t cgen_var_2;
stream->read((uint64_t*)&cgen_var_2, 8);
stream->handleMapping()->mapHandles_u64_VkQueue(&cgen_var_2, (VkQueue*)pQueue, 1);
+ sResourceTracker->on_vkGetDeviceQueue2(this, device, pQueueInfo, pQueue);
++encodeCount;;
if (0 == encodeCount % POOL_CLEAR_INTERVAL)
{
diff --git a/system/vulkan_enc/VulkanHandles.h b/system/vulkan_enc/VulkanHandles.h
index a233408..b0f4f6c 100644
--- a/system/vulkan_enc/VulkanHandles.h
+++ b/system/vulkan_enc/VulkanHandles.h
@@ -86,7 +86,6 @@
f(VkBufferView) \
f(VkImageView) \
f(VkShaderModule) \
- f(VkSampler) \
f(VkPipeline) \
f(VkPipelineCache) \
f(VkPipelineLayout) \
@@ -118,6 +117,7 @@
f(VkDescriptorSet) \
f(VkDescriptorSetLayout) \
f(VkCommandPool) \
+ f(VkSampler) \
__GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \
GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
@@ -129,6 +129,12 @@
GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f) \
GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f)
+#define GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_DISPATCHABLE_HANDLE_TYPES(f) \
+ f(VkInstance) \
+ f(VkDevice) \
+ f(VkQueue) \
+ GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f)
+
#define GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(f) \
f(VkDeviceMemory) \
f(VkBuffer) \
@@ -137,6 +143,7 @@
f(VkFence) \
f(VkDescriptorUpdateTemplate) \
f(VkCommandPool) \
+ f(VkSampler) \
__GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \
GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
diff --git a/system/vulkan_enc/func_table.cpp b/system/vulkan_enc/func_table.cpp
index b1b11b5..dc3f66d 100644
--- a/system/vulkan_enc/func_table.cpp
+++ b/system/vulkan_enc/func_table.cpp
@@ -1025,7 +1025,8 @@
AEMU_SCOPED_TRACE("vkAllocateCommandBuffers");
auto vkEnc = ResourceTracker::getThreadLocalEncoder();
VkResult vkAllocateCommandBuffers_VkResult_return = (VkResult)0;
- vkAllocateCommandBuffers_VkResult_return = vkEnc->vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, true /* do lock */);
+ auto resources = ResourceTracker::get();
+ vkAllocateCommandBuffers_VkResult_return = resources->on_vkAllocateCommandBuffers(vkEnc, VK_SUCCESS, device, pAllocateInfo, pCommandBuffers);
if (vkAllocateCommandBuffers_VkResult_return == VK_SUCCESS) {
ResourceTracker::get()->addToCommandPool(pAllocateInfo->commandPool, pAllocateInfo->commandBufferCount, pCommandBuffers);
}
diff --git a/system/vulkan_enc/vk_struct_id.h b/system/vulkan_enc/vk_struct_id.h
index 33e15f3..5cfb795 100644
--- a/system/vulkan_enc/vk_struct_id.h
+++ b/system/vulkan_enc/vk_struct_id.h
@@ -55,5 +55,6 @@
REGISTER_VK_STRUCT_ID(VkExternalImageFormatProperties, VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES);
REGISTER_VK_STRUCT_ID(VkPhysicalDeviceImageFormatInfo2, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2);
REGISTER_VK_STRUCT_ID(VkPhysicalDeviceExternalImageFormatInfo, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
+REGISTER_VK_STRUCT_ID(VkSemaphoreTypeCreateInfo, VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO);
#undef REGISTER_VK_STRUCT_ID