Add glMapBufferRange implemented via direct memory access
goldfish_address_space is a memory sharing device between
the QEMU host and an Android guest. This approach allows
to access host's memory from the guest directly without
copying bits.
Bug: 116046430
Test: Run the emulator with an OpenGL app that calls to
glMapBufferRange.
Change-Id: I1bee79e732fffe5eb853d4f511d707af624ae843
Signed-off-by: Roman Kiryanov <rkir@google.com>
diff --git a/GNUmakefile b/GNUmakefile
index 0610f29..9f3aa00 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -57,4 +57,4 @@
cmake:
@rm -f $(JSON_FILE)
$(call write-to-file,$(JSON_FILE),30,$(JSON_DUMP))
- $(hide) python cmake_transform.py -i $(JSON_FILE) -c $(JSON_FILE) -o ${_BUILD_ROOT}
\ No newline at end of file
+ $(hide) python cmake_transform.py -i $(JSON_FILE) -c $(JSON_FILE) -o ${_BUILD_ROOT}
diff --git a/shared/OpenglCodecCommon/Android.mk b/shared/OpenglCodecCommon/Android.mk
index 3971eae..5ca0a08 100644
--- a/shared/OpenglCodecCommon/Android.mk
+++ b/shared/OpenglCodecCommon/Android.mk
@@ -13,6 +13,7 @@
SocketStream.cpp \
TcpStream.cpp \
auto_goldfish_dma_context.cpp \
+ goldfish_address_space.cpp \
ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
diff --git a/shared/OpenglCodecCommon/CMakeLists.txt b/shared/OpenglCodecCommon/CMakeLists.txt
index 6f1f4ea..5d5ee8d 100644
--- a/shared/OpenglCodecCommon/CMakeLists.txt
+++ b/shared/OpenglCodecCommon/CMakeLists.txt
@@ -1,8 +1,8 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon/Android.mk" "b90bb271cb6f2c60c9d50bfe2a1273396e77e082d3482316f50185efdfb534c9")
-set(OpenglCodecCommon_host_src GLClientState.cpp GLESTextureUtils.cpp ChecksumCalculator.cpp GLSharedGroup.cpp glUtils.cpp IndexRangeCache.cpp SocketStream.cpp TcpStream.cpp auto_goldfish_dma_context.cpp goldfish_dma_host.cpp qemu_pipe_host.cpp)
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon/Android.mk" "8aaff0a6f86ae81d01d6e87b9477d200a774b95a3f15267921e4e1f9cbb9848e")
+set(OpenglCodecCommon_host_src GLClientState.cpp GLESTextureUtils.cpp ChecksumCalculator.cpp GLSharedGroup.cpp glUtils.cpp IndexRangeCache.cpp SocketStream.cpp TcpStream.cpp auto_goldfish_dma_context.cpp goldfish_address_space.cpp goldfish_dma_host.cpp qemu_pipe_host.cpp)
android_add_shared_library(OpenglCodecCommon_host)
target_include_directories(OpenglCodecCommon_host PRIVATE ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(OpenglCodecCommon_host PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"eglCodecCommon\"")
diff --git a/shared/OpenglCodecCommon/GLSharedGroup.h b/shared/OpenglCodecCommon/GLSharedGroup.h
index 9ef92ea..8a35a89 100755
--- a/shared/OpenglCodecCommon/GLSharedGroup.h
+++ b/shared/OpenglCodecCommon/GLSharedGroup.h
@@ -39,6 +39,7 @@
#include <utils/threads.h>
#include "FixedBuffer.h"
#include "auto_goldfish_dma_context.h"
+#include "goldfish_address_space.h"
#include "IndexRangeCache.h"
#include "SmartPtr.h"
@@ -63,6 +64,8 @@
// DMA support
AutoGoldfishDmaContext dma_buffer;
+ // Direct memory access support
+ GoldfishAddressSpaceBlock shared_block;
};
class ProgramData {
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.cpp b/shared/OpenglCodecCommon/goldfish_address_space.cpp
new file mode 100644
index 0000000..7852dc9
--- /dev/null
+++ b/shared/OpenglCodecCommon/goldfish_address_space.cpp
@@ -0,0 +1,194 @@
+#include <log/log.h>
+#include "goldfish_address_space.h"
+
+#ifdef GOLDFISH_OPENGL_BUILD_FOR_HOST
+GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock() : m_guest_ptr(NULL) {}
+
+bool GoldfishAddressSpaceBlock::allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size)
+{
+ return true;
+}
+
+uint64_t GoldfishAddressSpaceBlock::physAddr() const
+{
+ return 42; // some random number, not used
+}
+
+uint64_t GoldfishAddressSpaceBlock::hostAddr() const
+{
+ return 42; // some random number, not used
+}
+
+void *GoldfishAddressSpaceBlock::mmap(uint64_t opaque)
+{
+ m_guest_ptr = reinterpret_cast<void *>(opaque);
+ return m_guest_ptr;
+}
+
+void *GoldfishAddressSpaceBlock::guestPtr() const
+{
+ return m_guest_ptr;
+}
+
+void GoldfishAddressSpaceBlock::destroy()
+{
+ m_guest_ptr = NULL;
+}
+
+void GoldfishAddressSpaceBlock::replace(GoldfishAddressSpaceBlock *other)
+{
+ if (other) {
+ this->m_guest_ptr = other->m_guest_ptr;
+ other->m_guest_ptr = NULL;
+ } else {
+ this->m_guest_ptr = NULL;
+ }
+}
+#else
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <cstdlib>
+#include <errno.h>
+
+struct goldfish_address_space_allocate_block {
+ __u64 size;
+ __u64 offset;
+ __u64 phys_addr;
+};
+
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_MAGIC 'G'
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_OP(OP, T) _IOWR(GOLDFISH_ADDRESS_SPACE_IOCTL_MAGIC, OP, T)
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_ALLOCATE_BLOCK GOLDFISH_ADDRESS_SPACE_IOCTL_OP(10, struct goldfish_address_space_allocate_block)
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK GOLDFISH_ADDRESS_SPACE_IOCTL_OP(11, __u64)
+
+const char GOLDFISH_ADDRESS_SPACE_DEVICE_NAME[] = "/dev/goldfish_address_space";
+
+GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider()
+ : m_fd(::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR)) {}
+
+GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
+{
+ ::close(m_fd);
+}
+
+GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock()
+ : m_mmaped_ptr(NULL)
+ , m_phys_addr(0)
+ , m_host_addr(0)
+ , m_offset(0)
+ , m_size(0)
+ , m_fd(-1) {}
+
+GoldfishAddressSpaceBlock::~GoldfishAddressSpaceBlock()
+{
+ destroy();
+}
+
+GoldfishAddressSpaceBlock &GoldfishAddressSpaceBlock::operator=(const GoldfishAddressSpaceBlock &rhs)
+{
+ m_mmaped_ptr = rhs.m_mmaped_ptr;
+ m_phys_addr = rhs.m_phys_addr;
+ m_host_addr = rhs.m_host_addr;
+ m_offset = rhs.m_offset;
+ m_size = rhs.m_size;
+ m_fd = rhs.m_fd;
+
+ return *this;
+}
+
+bool GoldfishAddressSpaceBlock::allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size)
+{
+ destroy();
+
+ if (!provider->is_opened()) {
+ return false;
+ }
+
+ struct goldfish_address_space_allocate_block request;
+ long res;
+
+ request.size = size;
+ res = ::ioctl(provider->m_fd, GOLDFISH_ADDRESS_SPACE_IOCTL_ALLOCATE_BLOCK, &request);
+ if (res) {
+ return false;
+ } else {
+ m_phys_addr = request.phys_addr;
+ m_offset = request.offset;
+ m_size = request.size;
+ m_fd = provider->m_fd;
+ return true;
+ }
+}
+
+uint64_t GoldfishAddressSpaceBlock::physAddr() const
+{
+ return m_phys_addr;
+}
+
+uint64_t GoldfishAddressSpaceBlock::hostAddr() const
+{
+ return m_host_addr;
+}
+
+void *GoldfishAddressSpaceBlock::mmap(uint64_t host_addr)
+{
+ if (m_size == 0) {
+ return NULL;
+ }
+ if (m_mmaped_ptr) {
+ ALOGE("'mmap' called for an already mmaped address block");
+ ::abort();
+ }
+
+ void *result = ::mmap(NULL, m_size, PROT_WRITE, MAP_SHARED, m_fd, m_offset);
+ if (result == MAP_FAILED) {
+ return NULL;
+ } else {
+ m_mmaped_ptr = result;
+ m_host_addr = host_addr;
+ return guestPtr();
+ }
+}
+
+void *GoldfishAddressSpaceBlock::guestPtr() const
+{
+ return reinterpret_cast<char *>(m_mmaped_ptr) + (m_host_addr & (PAGE_SIZE - 1));
+}
+
+void GoldfishAddressSpaceBlock::destroy()
+{
+ if (m_mmaped_ptr && m_size) {
+ ::munmap(m_mmaped_ptr, m_size);
+ m_mmaped_ptr = NULL;
+ }
+
+ if (m_size) {
+ ::ioctl(m_fd, GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK, &m_offset);
+ m_phys_addr = 0;
+ m_host_addr = 0;
+ m_offset = 0;
+ m_size = 0;
+ }
+}
+
+void GoldfishAddressSpaceBlock::replace(GoldfishAddressSpaceBlock *other)
+{
+ destroy();
+
+ if (other) {
+ *this = *other;
+ *other = GoldfishAddressSpaceBlock();
+ }
+}
+
+bool GoldfishAddressSpaceBlockProvider::is_opened()
+{
+ return m_fd >= 0;
+}
+#endif
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h
new file mode 100644
index 0000000..dc784da
--- /dev/null
+++ b/shared/OpenglCodecCommon/goldfish_address_space.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
+#define ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
+
+#include <inttypes.h>
+
+class GoldfishAddressSpaceBlock;
+
+#ifdef GOLDFISH_OPENGL_BUILD_FOR_HOST
+class GoldfishAddressSpaceBlockProvider {};
+#else
+class GoldfishAddressSpaceBlockProvider {
+public:
+ GoldfishAddressSpaceBlockProvider();
+ ~GoldfishAddressSpaceBlockProvider();
+
+private:
+ GoldfishAddressSpaceBlockProvider(const GoldfishAddressSpaceBlockProvider &rhs);
+ GoldfishAddressSpaceBlockProvider &operator=(const GoldfishAddressSpaceBlockProvider &rhs);
+
+ bool is_opened();
+ int m_fd;
+
+ friend class GoldfishAddressSpaceBlock;
+};
+#endif
+
+class GoldfishAddressSpaceBlock {
+public:
+ GoldfishAddressSpaceBlock();
+ ~GoldfishAddressSpaceBlock();
+
+ bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size);
+ uint64_t physAddr() const;
+ uint64_t hostAddr() const;
+ void *mmap(uint64_t opaque);
+ void *guestPtr() const;
+ void replace(GoldfishAddressSpaceBlock *x);
+
+private:
+ void destroy();
+ GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &);
+
+#ifdef GOLDFISH_OPENGL_BUILD_FOR_HOST
+ void *m_guest_ptr;
+#else
+ void *m_mmaped_ptr;
+ uint64_t m_phys_addr;
+ uint64_t m_host_addr;
+ uint64_t m_offset;
+ size_t m_size;
+ int m_fd;
+#endif
+};
+
+#endif
diff --git a/system/GLESv1_enc/gl_client_proc.h b/system/GLESv1_enc/gl_client_proc.h
index 707c524..7d0f857 100644
--- a/system/GLESv1_enc/gl_client_proc.h
+++ b/system/GLESv1_enc/gl_client_proc.h
@@ -6,6 +6,9 @@
#include "gl_types.h"
+#ifdef _MSC_VER
+#include <stdint.h>
+#endif
#ifndef gl_APIENTRY
#define gl_APIENTRY
#endif
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index 220f198..daa891d 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -76,6 +76,7 @@
m_noHostError = false;
m_state = NULL;
m_error = GL_NO_ERROR;
+
m_num_compressedTextureFormats = 0;
m_max_combinedTextureImageUnits = 0;
m_max_vertexTextureImageUnits = 0;
@@ -2898,6 +2899,42 @@
buf->m_guest_paddr);
return reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr);
+ } else if (ctx->hasExtension("ANDROID_EMU_direct_mem")) {
+ GoldfishAddressSpaceBlock new_shared_block;
+
+ if (new_shared_block.allocate(&ctx->m_goldfish_address_block_provider, length)) {
+ uint64_t gpu_addr =
+ ctx->glMapBufferRangeDirect(ctx,
+ target,
+ offset,
+ length,
+ access,
+ new_shared_block.physAddr());
+ if (gpu_addr) {
+ void *user_ptr = new_shared_block.mmap(gpu_addr);
+ if (user_ptr) {
+ buf->shared_block.replace(&new_shared_block);
+ return user_ptr;
+ } else {
+ GLboolean host_res = GL_TRUE;
+
+ ctx->glUnmapBufferDirect(
+ ctx, target,
+ offset,
+ length,
+ access,
+ new_shared_block.physAddr(),
+ gpu_addr,
+ &host_res);
+
+ return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
+ }
+ } else {
+ return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
+ }
+ } else {
+ return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
+ }
} else {
return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
}
@@ -2934,12 +2971,29 @@
buf->m_mappedLength);
ctx->glUnmapBufferDMA(
+ ctx, target,
+ buf->m_mappedOffset,
+ buf->m_mappedLength,
+ buf->m_mappedAccess,
+ goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
+ &host_res);
+ } else if (buf->shared_block.guestPtr()) {
+ GoldfishAddressSpaceBlock *shared_block = &buf->shared_block;
+
+ memcpy(static_cast<char*>(buf->m_fixedBuffer.ptr()) + buf->m_mappedOffset,
+ shared_block->guestPtr(),
+ buf->m_mappedLength);
+
+ ctx->glUnmapBufferDirect(
ctx, target,
buf->m_mappedOffset,
buf->m_mappedLength,
buf->m_mappedAccess,
- goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
+ shared_block->physAddr(),
+ shared_block->hostAddr(),
&host_res);
+
+ shared_block->replace(NULL);
} else {
ctx->glUnmapBufferAEMU(
ctx, target,
@@ -2980,12 +3034,20 @@
buf->m_indexRangeCache.invalidateRange(totalOffset, length);
- ctx->glFlushMappedBufferRangeAEMU(
- ctx, target,
- totalOffset,
- length,
- buf->m_mappedAccess,
- (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
+ if (buf->shared_block.guestPtr()) {
+ ctx->glFlushMappedBufferRangeDirect(
+ ctx, target,
+ totalOffset,
+ length,
+ buf->m_mappedAccess);
+ } else {
+ ctx->glFlushMappedBufferRangeAEMU(
+ ctx, target,
+ totalOffset,
+ length,
+ buf->m_mappedAccess,
+ (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
+ }
}
void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
diff --git a/system/GLESv2_enc/GL2Encoder.h b/system/GLESv2_enc/GL2Encoder.h
index 5b51f7b..39f7feb 100644
--- a/system/GLESv2_enc/GL2Encoder.h
+++ b/system/GLESv2_enc/GL2Encoder.h
@@ -104,6 +104,8 @@
GLSharedGroupPtr m_shared;
GLenum m_error;
+ GoldfishAddressSpaceBlockProvider m_goldfish_address_block_provider;
+
GLint *m_compressedTextureFormats;
GLint m_num_compressedTextureFormats;
GLint *getCompressedTextureFormats();
diff --git a/system/GLESv2_enc/gl2_client_context.cpp b/system/GLESv2_enc/gl2_client_context.cpp
index 7da3e33..482b604 100644
--- a/system/GLESv2_enc/gl2_client_context.cpp
+++ b/system/GLESv2_enc/gl2_client_context.cpp
@@ -423,6 +423,9 @@
glGetTexLevelParameteriv = (glGetTexLevelParameteriv_client_proc_t) getProc("glGetTexLevelParameteriv", userData);
glMapBufferRangeDMA = (glMapBufferRangeDMA_client_proc_t) getProc("glMapBufferRangeDMA", userData);
glUnmapBufferDMA = (glUnmapBufferDMA_client_proc_t) getProc("glUnmapBufferDMA", userData);
+ glMapBufferRangeDirect = (glMapBufferRangeDirect_client_proc_t) getProc("glMapBufferRangeDirect", userData);
+ glUnmapBufferDirect = (glUnmapBufferDirect_client_proc_t) getProc("glUnmapBufferDirect", userData);
+ glFlushMappedBufferRangeDirect = (glFlushMappedBufferRangeDirect_client_proc_t) getProc("glFlushMappedBufferRangeDirect", userData);
return 0;
}
diff --git a/system/GLESv2_enc/gl2_client_context.h b/system/GLESv2_enc/gl2_client_context.h
index e2400a9..4a11c2a 100644
--- a/system/GLESv2_enc/gl2_client_context.h
+++ b/system/GLESv2_enc/gl2_client_context.h
@@ -423,6 +423,9 @@
glGetTexLevelParameteriv_client_proc_t glGetTexLevelParameteriv;
glMapBufferRangeDMA_client_proc_t glMapBufferRangeDMA;
glUnmapBufferDMA_client_proc_t glUnmapBufferDMA;
+ glMapBufferRangeDirect_client_proc_t glMapBufferRangeDirect;
+ glUnmapBufferDirect_client_proc_t glUnmapBufferDirect;
+ glFlushMappedBufferRangeDirect_client_proc_t glFlushMappedBufferRangeDirect;
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 8829c58..05d006a 100644
--- a/system/GLESv2_enc/gl2_client_proc.h
+++ b/system/GLESv2_enc/gl2_client_proc.h
@@ -6,6 +6,9 @@
#include "gl2_types.h"
+#ifdef _MSC_VER
+#include <stdint.h>
+#endif
#ifndef gl2_APIENTRY
#define gl2_APIENTRY
#endif
@@ -422,6 +425,9 @@
typedef void (gl2_APIENTRY *glGetTexLevelParameteriv_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLint*);
typedef void (gl2_APIENTRY *glMapBufferRangeDMA_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, uint64_t);
typedef void (gl2_APIENTRY *glUnmapBufferDMA_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, uint64_t, GLboolean*);
+typedef uint64_t (gl2_APIENTRY *glMapBufferRangeDirect_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, uint64_t);
+typedef void (gl2_APIENTRY *glUnmapBufferDirect_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, uint64_t, uint64_t, GLboolean*);
+typedef void (gl2_APIENTRY *glFlushMappedBufferRangeDirect_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield);
#endif
diff --git a/system/GLESv2_enc/gl2_enc.cpp b/system/GLESv2_enc/gl2_enc.cpp
index d5ae4b5..300994e 100644
--- a/system/GLESv2_enc/gl2_enc.cpp
+++ b/system/GLESv2_enc/gl2_enc.cpp
@@ -11116,6 +11116,122 @@
}
}
+uint64_t glMapBufferRangeDirect_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr)
+{
+
+ 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 + 8;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_glMapBufferRangeDirect;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &target, 4); ptr += 4;
+ memcpy(ptr, &offset, 4); ptr += 4;
+ memcpy(ptr, &length, 4); ptr += 4;
+ memcpy(ptr, &access, 4); ptr += 4;
+ memcpy(ptr, &paddr, 8); ptr += 8;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+ uint64_t retval;
+ stream->readback(&retval, 8);
+ if (useChecksum) checksumCalculator->addBuffer(&retval, 8);
+ 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("glMapBufferRangeDirect: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+ return retval;
+}
+
+void glUnmapBufferDirect_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, uint64_t guest_ptr, GLboolean* out_res)
+{
+
+ 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_out_res = (sizeof(GLboolean));
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 4 + 4 + 4 + 8 + 8 + 0 + 1*4;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_glUnmapBufferDirect;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &target, 4); ptr += 4;
+ memcpy(ptr, &offset, 4); ptr += 4;
+ memcpy(ptr, &length, 4); ptr += 4;
+ memcpy(ptr, &access, 4); ptr += 4;
+ memcpy(ptr, &paddr, 8); ptr += 8;
+ memcpy(ptr, &guest_ptr, 8); ptr += 8;
+ *(unsigned int *)(ptr) = __size_out_res; ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+ stream->readback(out_res, __size_out_res);
+ if (useChecksum) checksumCalculator->addBuffer(out_res, __size_out_res);
+ 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("glUnmapBufferDirect: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+}
+
+void glFlushMappedBufferRangeDirect_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+{
+
+ 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_glFlushMappedBufferRangeDirect;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &target, 4); ptr += 4;
+ memcpy(ptr, &offset, 4); ptr += 4;
+ memcpy(ptr, &length, 4); ptr += 4;
+ memcpy(ptr, &access, 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)
@@ -11536,5 +11652,8 @@
this->glGetTexLevelParameteriv = &glGetTexLevelParameteriv_enc;
this->glMapBufferRangeDMA = &glMapBufferRangeDMA_enc;
this->glUnmapBufferDMA = &glUnmapBufferDMA_enc;
+ this->glMapBufferRangeDirect = &glMapBufferRangeDirect_enc;
+ this->glUnmapBufferDirect = &glUnmapBufferDirect_enc;
+ this->glFlushMappedBufferRangeDirect = &glFlushMappedBufferRangeDirect_enc;
}
diff --git a/system/GLESv2_enc/gl2_entry.cpp b/system/GLESv2_enc/gl2_entry.cpp
index f60eb44..118b2ee 100644
--- a/system/GLESv2_enc/gl2_entry.cpp
+++ b/system/GLESv2_enc/gl2_entry.cpp
@@ -418,6 +418,9 @@
void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params);
void glMapBufferRangeDMA(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr);
void glUnmapBufferDMA(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, GLboolean* out_res);
+ uint64_t glMapBufferRangeDirect(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr);
+ void glUnmapBufferDirect(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, uint64_t guest_ptr, GLboolean* out_res);
+ void glFlushMappedBufferRangeDirect(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
};
#ifndef GET_CONTEXT
@@ -2941,3 +2944,21 @@
ctx->glUnmapBufferDMA(ctx, target, offset, length, access, paddr, out_res);
}
+uint64_t glMapBufferRangeDirect(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr)
+{
+ GET_CONTEXT;
+ return ctx->glMapBufferRangeDirect(ctx, target, offset, length, access, paddr);
+}
+
+void glUnmapBufferDirect(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, uint64_t guest_ptr, GLboolean* out_res)
+{
+ GET_CONTEXT;
+ ctx->glUnmapBufferDirect(ctx, target, offset, length, access, paddr, guest_ptr, out_res);
+}
+
+void glFlushMappedBufferRangeDirect(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+{
+ GET_CONTEXT;
+ ctx->glFlushMappedBufferRangeDirect(ctx, target, offset, length, access);
+}
+
diff --git a/system/GLESv2_enc/gl2_opcodes.h b/system/GLESv2_enc/gl2_opcodes.h
index 2affe0e..b359570 100644
--- a/system/GLESv2_enc/gl2_opcodes.h
+++ b/system/GLESv2_enc/gl2_opcodes.h
@@ -416,7 +416,10 @@
#define OP_glGetTexLevelParameteriv 2458
#define OP_glMapBufferRangeDMA 2459
#define OP_glUnmapBufferDMA 2460
-#define OP_last 2461
+#define OP_glMapBufferRangeDirect 2461
+#define OP_glUnmapBufferDirect 2462
+#define OP_glFlushMappedBufferRangeDirect 2463
+#define OP_last 2464
#endif
diff --git a/system/renderControl_enc/renderControl_client_proc.h b/system/renderControl_enc/renderControl_client_proc.h
index 24708dd..2dc7486 100644
--- a/system/renderControl_enc/renderControl_client_proc.h
+++ b/system/renderControl_enc/renderControl_client_proc.h
@@ -6,6 +6,9 @@
#include "renderControl_types.h"
+#ifdef _MSC_VER
+#include <stdint.h>
+#endif
#ifndef renderControl_APIENTRY
#define renderControl_APIENTRY
#endif