rcReadColorBufferDMA + host side ColorBuffer create opts
Bug: 189960317
Change-Id: I2c45bd89c46a6b0f2ab5488b190f8a70c119118d
diff --git a/protocols/generic-apigen/ApiGen.cpp b/protocols/generic-apigen/ApiGen.cpp
index 1238512..5f140c6 100644
--- a/protocols/generic-apigen/ApiGen.cpp
+++ b/protocols/generic-apigen/ApiGen.cpp
@@ -792,11 +792,19 @@
if (evars[j].guestUnpackExpression() != "") {
fprintf(fp, "%s%s;\n", indent, evars[j].guestUnpackExpression().c_str());
} else {
- fprintf(fp, "%sstream->readback(%s, __size_%s);\n",
+ if (evars[j].isDMA()) {
+ fprintf(fp, "%s// Skip readback for var %s as it's DMA\n", indent, varname);
+ } else {
+ fprintf(fp, "%sstream->readback(%s, __size_%s);\n",
+ indent, varname, varname);
+ }
+ }
+ if (evars[j].isDMA()) {
+ fprintf(fp, "%s// Skip checksum for var %s as it's DMA\n", indent, varname);
+ } else {
+ fprintf(fp, "%sif (useChecksum) checksumCalculator->addBuffer(%s, __size_%s);\n",
indent, varname, varname);
}
- fprintf(fp, "%sif (useChecksum) checksumCalculator->addBuffer(%s, __size_%s);\n",
- indent, varname, varname);
if (evars[j].nullAllowed()) {
fprintf(fp, "\t}\n");
}
diff --git a/protocols/renderControl/renderControl.attrib b/protocols/renderControl/renderControl.attrib
index d8c3ac1..5cd75f0 100644
--- a/protocols/renderControl/renderControl.attrib
+++ b/protocols/renderControl/renderControl.attrib
@@ -111,3 +111,9 @@
dir buffer in
len buffer bufferSize
flag flushOnEncode
+
+rcReadColorBufferDMA
+ dir pixels out
+ len pixels pixels_size
+ var_flag pixels DMA
+
diff --git a/protocols/renderControl/renderControl.in b/protocols/renderControl/renderControl.in
index 5be924e..acd2ca8 100644
--- a/protocols/renderControl/renderControl.in
+++ b/protocols/renderControl/renderControl.in
@@ -62,3 +62,4 @@
GL_ENTRY(void, rcComposeAsyncWithoutPost, uint32_t bufferSize, void *buffer);
GL_ENTRY(int, rcCreateDisplayById, uint32_t displayId);
GL_ENTRY(int, rcSetDisplayPoseDpi, uint32_t displayId, GLint x, GLint y, uint32_t w, uint32_t h, uint32_t dpi);
+GL_ENTRY(int, rcReadColorBufferDMA, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels, uint32_t pixels_size)
diff --git a/stream-servers/RenderControl.cpp b/stream-servers/RenderControl.cpp
index b03ac7e..3333f7f 100644
--- a/stream-servers/RenderControl.cpp
+++ b/stream-servers/RenderControl.cpp
@@ -238,6 +238,9 @@
// Async vkQSRI
static const char* kVulkanAsyncQsri = "ANDROID_EMU_vulkan_async_qsri";
+// Read color buffer DMA
+static const char* kReadColorBufferDma = "ANDROID_EMU_read_color_buffer_dma";
+
static void rcTriggerWait(uint64_t glsync_ptr,
uint64_t thread_ptr,
uint64_t timeline);
@@ -492,6 +495,7 @@
bool vulkanBatchedDescriptorSetUpdate = shouldEnableBatchedDescriptorSetUpdate();
bool syncBufferDataEnabled = true;
bool vulkanAsyncQsri = shouldEnableVulkanAsyncQsri();
+ bool readColorBufferDma = directMemEnabled && hasSharedSlotsHostMemoryAllocatorEnabled;
if (isChecksumEnabled && name == GL_EXTENSIONS) {
glStr += ChecksumCalculatorThreadInfo::getMaxVersionString();
@@ -625,6 +629,11 @@
glStr += " ";
}
+ if (readColorBufferDma) {
+ glStr += kReadColorBufferDma;
+ glStr += " ";
+ }
+
if (name == GL_EXTENSIONS) {
GLESDispatchMaxVersion guestExtVer = GLES_DISPATCH_MAX_VERSION_2;
@@ -1532,6 +1541,23 @@
fenceSync->decRef();
}
+static int rcReadColorBufferDMA(uint32_t colorBuffer,
+ GLint x, GLint y,
+ GLint width, GLint height,
+ GLenum format, GLenum type, void* pixels, uint32_t pixels_size)
+{
+ FrameBuffer *fb = FrameBuffer::getFB();
+ if (!fb) {
+ return -1;
+ }
+
+ // Update from Vulkan if necessary
+ goldfish_vk::updateColorBufferFromVkImage(colorBuffer);
+
+ fb->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
+ return 0;
+}
+
void initRenderControlContext(renderControl_decoder_context_t *dec)
{
dec->rcGetRendererVersion = rcGetRendererVersion;
@@ -1598,4 +1624,5 @@
dec->rcComposeAsyncWithoutPost = rcComposeAsyncWithoutPost;
dec->rcCreateDisplayById = rcCreateDisplayById;
dec->rcSetDisplayPoseDpi = rcSetDisplayPoseDpi;
+ dec->rcReadColorBufferDMA = rcReadColorBufferDMA;
}
diff --git a/stream-servers/renderControl_dec/renderControl_dec.cpp b/stream-servers/renderControl_dec/renderControl_dec.cpp
index 8b27562..61c8f14 100644
--- a/stream-servers/renderControl_dec/renderControl_dec.cpp
+++ b/stream-servers/renderControl_dec/renderControl_dec.cpp
@@ -1265,6 +1265,36 @@
android::base::endTrace();
break;
}
+ case OP_rcReadColorBufferDMA: {
+ android::base::beginTrace("rcReadColorBufferDMA decode");
+ uint32_t var_colorbuffer = Unpack<uint32_t,uint32_t>(ptr + 8);
+ GLint var_x = Unpack<GLint,uint32_t>(ptr + 8 + 4);
+ GLint var_y = Unpack<GLint,uint32_t>(ptr + 8 + 4 + 4);
+ GLint var_width = Unpack<GLint,uint32_t>(ptr + 8 + 4 + 4 + 4);
+ GLint var_height = Unpack<GLint,uint32_t>(ptr + 8 + 4 + 4 + 4 + 4);
+ GLenum var_format = Unpack<GLenum,uint32_t>(ptr + 8 + 4 + 4 + 4 + 4 + 4);
+ GLenum var_type = Unpack<GLenum,uint32_t>(ptr + 8 + 4 + 4 + 4 + 4 + 4 + 4);
+ uint64_t var_pixels_guest_paddr = Unpack<uint64_t,uint64_t>(ptr + 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+ void* var_pixels = stream->getDmaForReading(var_pixels_guest_paddr);
+ uint32_t size_pixels __attribute__((unused)) = Unpack<uint32_t,uint32_t>(ptr + 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 8);
+ uint32_t var_pixels_size = Unpack<uint32_t,uint32_t>(ptr + 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 8);
+ if (useChecksum) {
+ ChecksumCalculatorThreadInfo::validOrDie(checksumCalc, ptr, 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 8 + 4, ptr + 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 8 + 4, checksumSize,
+ "renderControl_decoder_context_t::decode, OP_rcReadColorBufferDMA: GL checksumCalculator failure\n");
+ }
+ size_t totalTmpSize = sizeof(int);
+ totalTmpSize += checksumSize;
+ unsigned char *tmpBuf = stream->alloc(totalTmpSize);
+ *(int *)(&tmpBuf[0]) = this->rcReadColorBufferDMA(var_colorbuffer, var_x, var_y, var_width, var_height, var_format, var_type, var_pixels, var_pixels_size);
+ stream->unlockDma(var_pixels_guest_paddr);
+ if (useChecksum) {
+ ChecksumCalculatorThreadInfo::writeChecksum(checksumCalc, &tmpBuf[0], totalTmpSize - checksumSize, &tmpBuf[totalTmpSize - checksumSize], checksumSize);
+ }
+ stream->flush();
+ SET_LASTCALL("rcReadColorBufferDMA");
+ android::base::endTrace();
+ break;
+ }
default:
return ptr - (unsigned char*)buf;
} //switch
diff --git a/stream-servers/renderControl_dec/renderControl_opcodes.h b/stream-servers/renderControl_dec/renderControl_opcodes.h
index 732d3e0..00249d6 100644
--- a/stream-servers/renderControl_dec/renderControl_opcodes.h
+++ b/stream-servers/renderControl_dec/renderControl_opcodes.h
@@ -67,7 +67,8 @@
#define OP_rcComposeAsyncWithoutPost 10061
#define OP_rcCreateDisplayById 10062
#define OP_rcSetDisplayPoseDpi 10063
-#define OP_last 10064
+#define OP_rcReadColorBufferDMA 10064
+#define OP_last 10065
#endif
diff --git a/stream-servers/renderControl_dec/renderControl_server_context.cpp b/stream-servers/renderControl_dec/renderControl_server_context.cpp
index c6cbf23..e840603 100644
--- a/stream-servers/renderControl_dec/renderControl_server_context.cpp
+++ b/stream-servers/renderControl_dec/renderControl_server_context.cpp
@@ -74,6 +74,7 @@
rcComposeAsyncWithoutPost = (rcComposeAsyncWithoutPost_server_proc_t) getProc("rcComposeAsyncWithoutPost", userData);
rcCreateDisplayById = (rcCreateDisplayById_server_proc_t) getProc("rcCreateDisplayById", userData);
rcSetDisplayPoseDpi = (rcSetDisplayPoseDpi_server_proc_t) getProc("rcSetDisplayPoseDpi", userData);
+ rcReadColorBufferDMA = (rcReadColorBufferDMA_server_proc_t) getProc("rcReadColorBufferDMA", userData);
return 0;
}
diff --git a/stream-servers/renderControl_dec/renderControl_server_context.h b/stream-servers/renderControl_dec/renderControl_server_context.h
index f151288..7a9640c 100644
--- a/stream-servers/renderControl_dec/renderControl_server_context.h
+++ b/stream-servers/renderControl_dec/renderControl_server_context.h
@@ -74,6 +74,7 @@
rcComposeAsyncWithoutPost_server_proc_t rcComposeAsyncWithoutPost;
rcCreateDisplayById_server_proc_t rcCreateDisplayById;
rcSetDisplayPoseDpi_server_proc_t rcSetDisplayPoseDpi;
+ rcReadColorBufferDMA_server_proc_t rcReadColorBufferDMA;
virtual ~renderControl_server_context_t() {}
int initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);
};
diff --git a/stream-servers/renderControl_dec/renderControl_server_proc.h b/stream-servers/renderControl_dec/renderControl_server_proc.h
index 84d192a..c3769eb 100644
--- a/stream-servers/renderControl_dec/renderControl_server_proc.h
+++ b/stream-servers/renderControl_dec/renderControl_server_proc.h
@@ -76,6 +76,7 @@
typedef void (renderControl_APIENTRY *rcComposeAsyncWithoutPost_server_proc_t) (uint32_t, void*);
typedef int (renderControl_APIENTRY *rcCreateDisplayById_server_proc_t) (uint32_t);
typedef int (renderControl_APIENTRY *rcSetDisplayPoseDpi_server_proc_t) (uint32_t, GLint, GLint, uint32_t, uint32_t, uint32_t);
+typedef int (renderControl_APIENTRY *rcReadColorBufferDMA_server_proc_t) (uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*, uint32_t);
#endif