Support for calling null draws from the guest
bug: 123635308
Change-Id: I039abf4d7de08747e11aeebc28fd5bde6e77d7b4
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index 3515d9e..ff88b31 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -123,6 +123,8 @@
OVERRIDE(glDeleteBuffers);
OVERRIDE(glDrawArrays);
OVERRIDE(glDrawElements);
+ OVERRIDE(glDrawArraysNullAEMU);
+ OVERRIDE(glDrawElementsNullAEMU);
OVERRIDE(glGetIntegerv);
OVERRIDE(glGetFloatv);
OVERRIDE(glGetBooleanv);
@@ -1426,6 +1428,120 @@
}
}
+void GL2Encoder::s_glDrawArraysNullAEMU(void *self, GLenum mode, GLint first, GLsizei count)
+{
+ GL2Encoder *ctx = (GL2Encoder *)self;
+ assert(ctx->m_state != NULL);
+ SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
+ SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
+
+ bool has_client_vertex_arrays = false;
+ bool has_indirect_arrays = false;
+ ctx->getVBOUsage(&has_client_vertex_arrays,
+ &has_indirect_arrays);
+
+ if (has_client_vertex_arrays ||
+ (!has_client_vertex_arrays &&
+ !has_indirect_arrays)) {
+ ctx->sendVertexAttributes(first, count, true);
+ ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, 0, count);
+ } else {
+ ctx->sendVertexAttributes(0, count, false);
+ ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, first, count);
+ }
+}
+
+void GL2Encoder::s_glDrawElementsNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+
+ GL2Encoder *ctx = (GL2Encoder *)self;
+ assert(ctx->m_state != NULL);
+ SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
+ SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
+ SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
+ SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
+
+ bool has_client_vertex_arrays = false;
+ bool has_indirect_arrays = false;
+ int nLocations = ctx->m_state->nLocations();
+ GLintptr offset = 0;
+
+ ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
+
+ if (!has_client_vertex_arrays && !has_indirect_arrays) {
+ // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
+ GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
+ SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ BufferData* buf = NULL;
+ int minIndex = 0, maxIndex = 0;
+
+ // For validation/immediate index array purposes,
+ // we need the min/max vertex index of the index array.
+ // If the VBO != 0, this may not be the first time we have
+ // used this particular index buffer. getBufferIndexRange
+ // can more quickly get min/max vertex index by
+ // caching previous results.
+ if (ctx->m_state->currentIndexVbo() != 0) {
+ buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
+ offset = (GLintptr)indices;
+ indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
+ ctx->getBufferIndexRange(buf,
+ indices,
+ type,
+ (size_t)count,
+ (size_t)offset,
+ &minIndex, &maxIndex);
+ } else {
+ // In this case, the |indices| field holds a real
+ // array, so calculate the indices now. They will
+ // also be needed to know how much data to
+ // transfer to host.
+ ctx->calcIndexRange(indices,
+ type,
+ count,
+ &minIndex,
+ &maxIndex);
+ }
+
+ if (count == 0) return;
+
+ bool adjustIndices = true;
+ if (ctx->m_state->currentIndexVbo() != 0) {
+ if (!has_client_vertex_arrays) {
+ ctx->sendVertexAttributes(0, maxIndex + 1, false);
+ ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
+ ctx->glDrawElementsOffsetNullAEMU(ctx, mode, count, type, offset);
+ ctx->flushDrawCall();
+ adjustIndices = false;
+ } else {
+ BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
+ ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+ }
+ if (adjustIndices) {
+ void *adjustedIndices =
+ ctx->recenterIndices(indices,
+ type,
+ count,
+ minIndex);
+
+ if (has_indirect_arrays || 1) {
+ ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
+ ctx->glDrawElementsDataNullAEMU(ctx, mode, count, type, adjustedIndices,
+ count * glSizeof(type));
+ // XXX - OPTIMIZATION (see the other else branch) should be implemented
+ if(!has_indirect_arrays) {
+ //ALOGD("unoptimized drawelements !!!\n");
+ }
+ } else {
+ // we are all direct arrays and immidate mode index array -
+ // rebuild the arrays and the index array;
+ ALOGE("glDrawElementsNullAEMU: direct index & direct buffer data - will be implemented in later versions;\n");
+ }
+ }
+}
GLint * GL2Encoder::getCompressedTextureFormats()
{
diff --git a/system/GLESv2_enc/GL2Encoder.h b/system/GLESv2_enc/GL2Encoder.h
index 35d4737..a25f071 100644
--- a/system/GLESv2_enc/GL2Encoder.h
+++ b/system/GLESv2_enc/GL2Encoder.h
@@ -205,6 +205,12 @@
glDrawElements_client_proc_t m_glDrawElements_enc;
static void s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices);
+ glDrawArraysNullAEMU_client_proc_t m_glDrawArraysNullAEMU_enc;
+ static void s_glDrawArraysNullAEMU(void *self, GLenum mode, GLint first, GLsizei count);
+
+ glDrawElementsNullAEMU_client_proc_t m_glDrawElementsNullAEMU_enc;
+ static void s_glDrawElementsNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices);
+
glGetIntegerv_client_proc_t m_glGetIntegerv_enc;
static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr);
diff --git a/system/GLESv2_enc/gl2_client_context.cpp b/system/GLESv2_enc/gl2_client_context.cpp
index 783ecd0..c811b66 100644
--- a/system/GLESv2_enc/gl2_client_context.cpp
+++ b/system/GLESv2_enc/gl2_client_context.cpp
@@ -430,6 +430,10 @@
glReadnPixelsEXT = (glReadnPixelsEXT_client_proc_t) getProc("glReadnPixelsEXT", userData);
glGetnUniformfvEXT = (glGetnUniformfvEXT_client_proc_t) getProc("glGetnUniformfvEXT", userData);
glGetnUniformivEXT = (glGetnUniformivEXT_client_proc_t) getProc("glGetnUniformivEXT", userData);
+ glDrawArraysNullAEMU = (glDrawArraysNullAEMU_client_proc_t) getProc("glDrawArraysNullAEMU", userData);
+ glDrawElementsNullAEMU = (glDrawElementsNullAEMU_client_proc_t) getProc("glDrawElementsNullAEMU", userData);
+ glDrawElementsOffsetNullAEMU = (glDrawElementsOffsetNullAEMU_client_proc_t) getProc("glDrawElementsOffsetNullAEMU", userData);
+ glDrawElementsDataNullAEMU = (glDrawElementsDataNullAEMU_client_proc_t) getProc("glDrawElementsDataNullAEMU", userData);
return 0;
}
diff --git a/system/GLESv2_enc/gl2_client_context.h b/system/GLESv2_enc/gl2_client_context.h
index fe5c893..ce0cf47 100644
--- a/system/GLESv2_enc/gl2_client_context.h
+++ b/system/GLESv2_enc/gl2_client_context.h
@@ -430,6 +430,10 @@
glReadnPixelsEXT_client_proc_t glReadnPixelsEXT;
glGetnUniformfvEXT_client_proc_t glGetnUniformfvEXT;
glGetnUniformivEXT_client_proc_t glGetnUniformivEXT;
+ glDrawArraysNullAEMU_client_proc_t glDrawArraysNullAEMU;
+ glDrawElementsNullAEMU_client_proc_t glDrawElementsNullAEMU;
+ glDrawElementsOffsetNullAEMU_client_proc_t glDrawElementsOffsetNullAEMU;
+ glDrawElementsDataNullAEMU_client_proc_t glDrawElementsDataNullAEMU;
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 1237dad..dea6d12 100644
--- a/system/GLESv2_enc/gl2_client_proc.h
+++ b/system/GLESv2_enc/gl2_client_proc.h
@@ -432,6 +432,10 @@
typedef void (gl2_APIENTRY *glReadnPixelsEXT_client_proc_t) (void * ctx, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLsizei, GLvoid*);
typedef void (gl2_APIENTRY *glGetnUniformfvEXT_client_proc_t) (void * ctx, GLuint, GLint, GLsizei, GLfloat*);
typedef void (gl2_APIENTRY *glGetnUniformivEXT_client_proc_t) (void * ctx, GLuint, GLint, GLsizei, GLint*);
+typedef void (gl2_APIENTRY *glDrawArraysNullAEMU_client_proc_t) (void * ctx, GLenum, GLint, GLsizei);
+typedef void (gl2_APIENTRY *glDrawElementsNullAEMU_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, const GLvoid*);
+typedef void (gl2_APIENTRY *glDrawElementsOffsetNullAEMU_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glDrawElementsDataNullAEMU_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, void*, GLuint);
#endif
diff --git a/system/GLESv2_enc/gl2_enc.cpp b/system/GLESv2_enc/gl2_enc.cpp
index 6fecec4..17b3cba 100644
--- a/system/GLESv2_enc/gl2_enc.cpp
+++ b/system/GLESv2_enc/gl2_enc.cpp
@@ -11396,6 +11396,92 @@
}
}
+void glDrawArraysNullAEMU_enc(void *self , GLenum mode, GLint first, GLsizei count)
+{
+
+ 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;
+
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 4 + 4;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_glDrawArraysNullAEMU;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &mode, 4); ptr += 4;
+ memcpy(ptr, &first, 4); ptr += 4;
+ memcpy(ptr, &count, 4); ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+}
+
+void glDrawElementsOffsetNullAEMU_enc(void *self , GLenum mode, GLsizei count, GLenum type, GLuint offset)
+{
+
+ 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;
+
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 4 + 4 + 4;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_glDrawElementsOffsetNullAEMU;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &mode, 4); ptr += 4;
+ memcpy(ptr, &count, 4); ptr += 4;
+ memcpy(ptr, &type, 4); ptr += 4;
+ memcpy(ptr, &offset, 4); ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+}
+
+void glDrawElementsDataNullAEMU_enc(void *self , GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen)
+{
+
+ 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 = datalen;
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 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_glDrawElementsDataNullAEMU;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &mode, 4); ptr += 4;
+ memcpy(ptr, &count, 4); ptr += 4;
+ memcpy(ptr, &type, 4); ptr += 4;
+ *(unsigned int *)(ptr) = __size_data; ptr += 4;
+ memcpy(ptr, data, __size_data);ptr += __size_data;
+ memcpy(ptr, &datalen, 4); ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+}
+
} // namespace
gl2_encoder_context_t::gl2_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator)
@@ -11823,5 +11909,9 @@
this->glReadnPixelsEXT = &glReadnPixelsEXT_enc;
this->glGetnUniformfvEXT = &glGetnUniformfvEXT_enc;
this->glGetnUniformivEXT = &glGetnUniformivEXT_enc;
+ this->glDrawArraysNullAEMU = &glDrawArraysNullAEMU_enc;
+ this->glDrawElementsNullAEMU = (glDrawElementsNullAEMU_client_proc_t) &enc_unsupported;
+ this->glDrawElementsOffsetNullAEMU = &glDrawElementsOffsetNullAEMU_enc;
+ this->glDrawElementsDataNullAEMU = &glDrawElementsDataNullAEMU_enc;
}
diff --git a/system/GLESv2_enc/gl2_entry.cpp b/system/GLESv2_enc/gl2_entry.cpp
index 70b22bc..69ce39d 100644
--- a/system/GLESv2_enc/gl2_entry.cpp
+++ b/system/GLESv2_enc/gl2_entry.cpp
@@ -425,6 +425,10 @@
void glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid* data);
void glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
void glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params);
+ void glDrawArraysNullAEMU(GLenum mode, GLint first, GLsizei count);
+ void glDrawElementsNullAEMU(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+ void glDrawElementsOffsetNullAEMU(GLenum mode, GLsizei count, GLenum type, GLuint offset);
+ void glDrawElementsDataNullAEMU(GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen);
};
#ifndef GET_CONTEXT
@@ -2990,3 +2994,27 @@
ctx->glGetnUniformivEXT(ctx, program, location, bufSize, params);
}
+void glDrawArraysNullAEMU(GLenum mode, GLint first, GLsizei count)
+{
+ GET_CONTEXT;
+ ctx->glDrawArraysNullAEMU(ctx, mode, first, count);
+}
+
+void glDrawElementsNullAEMU(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+ GET_CONTEXT;
+ ctx->glDrawElementsNullAEMU(ctx, mode, count, type, indices);
+}
+
+void glDrawElementsOffsetNullAEMU(GLenum mode, GLsizei count, GLenum type, GLuint offset)
+{
+ GET_CONTEXT;
+ ctx->glDrawElementsOffsetNullAEMU(ctx, mode, count, type, offset);
+}
+
+void glDrawElementsDataNullAEMU(GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen)
+{
+ GET_CONTEXT;
+ ctx->glDrawElementsDataNullAEMU(ctx, mode, count, type, data, datalen);
+}
+
diff --git a/system/GLESv2_enc/gl2_ftable.h b/system/GLESv2_enc/gl2_ftable.h
index 0e93cf1..ff3de2e 100644
--- a/system/GLESv2_enc/gl2_ftable.h
+++ b/system/GLESv2_enc/gl2_ftable.h
@@ -385,6 +385,8 @@
{"glReadnPixelsEXT", (void*)glReadnPixelsEXT},
{"glGetnUniformfvEXT", (void*)glGetnUniformfvEXT},
{"glGetnUniformivEXT", (void*)glGetnUniformivEXT},
+ {"glDrawArraysNullAEMU", (void*)glDrawArraysNullAEMU},
+ {"glDrawElementsNullAEMU", (void*)glDrawElementsNullAEMU},
};
static const int gl2_num_funcs = sizeof(gl2_funcs_by_name) / sizeof(struct _gl2_funcs_by_name);
diff --git a/system/GLESv2_enc/gl2_opcodes.h b/system/GLESv2_enc/gl2_opcodes.h
index 96688db..7628a2e 100644
--- a/system/GLESv2_enc/gl2_opcodes.h
+++ b/system/GLESv2_enc/gl2_opcodes.h
@@ -423,7 +423,11 @@
#define OP_glReadnPixelsEXT 2465
#define OP_glGetnUniformfvEXT 2466
#define OP_glGetnUniformivEXT 2467
-#define OP_last 2468
+#define OP_glDrawArraysNullAEMU 2468
+#define OP_glDrawElementsNullAEMU 2469
+#define OP_glDrawElementsOffsetNullAEMU 2470
+#define OP_glDrawElementsDataNullAEMU 2471
+#define OP_last 2472
#endif