tracing prototype: guest-side changes for gfxstream
Bug: 168843698
Change-Id: I22a7568bb8b28b8b3bafda7100dee4c2d7a6fe50
diff --git a/android-emu/android/base/Tracing.cpp b/android-emu/android/base/Tracing.cpp
index 0e635db..dd8e44b 100644
--- a/android-emu/android/base/Tracing.cpp
+++ b/android-emu/android/base/Tracing.cpp
@@ -25,6 +25,10 @@
namespace android {
namespace base {
+bool isTracingEnabled() {
+ return atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS);
+}
+
void ScopedTraceGuest::beginTraceImpl(const char* name) {
atrace_begin(VK_TRACE_TAG, name);
}
@@ -47,6 +51,11 @@
namespace android {
namespace base {
+bool isTracingEnabled() {
+ // TODO: Fuchsia
+ return false;
+}
+
void ScopedTraceGuest::beginTraceImpl(const char* name) {
#ifndef FUCHSIA_NO_TRACE
TRACE_DURATION_BEGIN(VK_TRACE_TAG, name);
diff --git a/android-emu/android/base/Tracing.h b/android-emu/android/base/Tracing.h
index 3a78726..e13d202 100644
--- a/android-emu/android/base/Tracing.h
+++ b/android-emu/android/base/Tracing.h
@@ -16,6 +16,7 @@
// Library to perform tracing. Talks to platform-specific
// tracing libraries.
+
namespace android {
namespace base {
@@ -23,6 +24,11 @@
void initializeTracing();
void enableTracing();
void disableTracing();
+// Some platform tracing libraries such as Perfetto can be enabled/disabled at
+// runtime. Allow the user to query if they are disabled or not, and take
+// further action based on it. The use case is to enable/disable tracing on the
+// host alongside.
+bool isTracingEnabled();
class ScopedTrace {
public:
@@ -36,6 +42,8 @@
};
#endif
+bool isTracingEnabled();
+
class ScopedTraceGuest {
public:
ScopedTraceGuest(const char* name) : name_(name) {
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index 304ab36..da15346 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -117,6 +117,9 @@
// A flag to _not_ ignore host opengl errors (now host opengl errors are ignored by default)
static const char kGLESUseHostError[] = "ANDROID_EMU_gles_use_host_error";
+// Host side tracing
+static const char kHostSideTracing[] = "ANDROID_EMU_host_side_tracing";
+
// Struct describing available emulator features
struct EmulatorFeatureInfo {
@@ -138,7 +141,8 @@
hasVulkanFreeMemorySync(false),
hasVirtioGpuNativeSync(false),
hasVulkanShaderFloat16Int8(false),
- hasVulkanAsyncQueueSubmit(false)
+ hasVulkanAsyncQueueSubmit(false),
+ hasHostSideTracing(false)
{ }
SyncImpl syncImpl;
@@ -159,6 +163,7 @@
bool hasVirtioGpuNativeSync;
bool hasVulkanShaderFloat16Int8;
bool hasVulkanAsyncQueueSubmit;
+ bool hasHostSideTracing;
};
enum HostConnectionType {
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 7ddf277..540f6c4 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -655,6 +655,7 @@
queryAndSetVirtioGpuNativeSync(rcEnc);
queryAndSetVulkanShaderFloat16Int8Support(rcEnc);
queryAndSetVulkanAsyncQueueSubmitSupport(rcEnc);
+ queryAndSetHostSideTracingSupport(rcEnc);
if (m_processPipe) {
m_processPipe->processPipeInit(m_connectionType, rcEnc);
}
@@ -917,3 +918,10 @@
rcEnc->featureInfo()->hasVulkanAsyncQueueSubmit = true;
}
}
+
+void HostConnection::queryAndSetHostSideTracingSupport(ExtendedRCEncoderContext* rcEnc) {
+ std::string glExtensions = queryGLExtensions(rcEnc);
+ if (glExtensions.find(kHostSideTracing) != std::string::npos) {
+ rcEnc->featureInfo()->hasHostSideTracing = true;
+ }
+}
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index 32a1521..1220628 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -65,6 +65,9 @@
return m_featureInfo.hasYUVCache; }
bool hasAsyncUnmapBuffer() const {
return m_featureInfo.hasAsyncUnmapBuffer; }
+ bool hasHostSideTracing() const {
+ return m_featureInfo.hasHostSideTracing;
+ }
DmaImpl getDmaVersion() const { return m_featureInfo.dmaImpl; }
void bindDmaContext(struct goldfish_dma_context* cxt) { m_dmaCxt = cxt; }
void bindDmaDirectly(void* dmaPtr, uint64_t dmaPhysAddr) {
@@ -217,6 +220,7 @@
void queryAndSetVirtioGpuNativeSync(ExtendedRCEncoderContext *rcEnc);
void queryAndSetVulkanShaderFloat16Int8Support(ExtendedRCEncoderContext *rcEnc);
void queryAndSetVulkanAsyncQueueSubmitSupport(ExtendedRCEncoderContext *rcEnc);
+ void queryAndSetHostSideTracingSupport(ExtendedRCEncoderContext *rcEnc);
private:
HostConnectionType m_connectionType;
diff --git a/system/OpenglSystemCommon/ProcessPipe.cpp b/system/OpenglSystemCommon/ProcessPipe.cpp
index c79bf17..bca6388 100644
--- a/system/OpenglSystemCommon/ProcessPipe.cpp
+++ b/system/OpenglSystemCommon/ProcessPipe.cpp
@@ -208,3 +208,7 @@
rcEnc->rcSetPuid(rcEnc, sProcUID);
return true;
}
+
+uint64_t getPuid() {
+ return sProcUID;
+}
diff --git a/system/OpenglSystemCommon/ProcessPipe.h b/system/OpenglSystemCommon/ProcessPipe.h
index dea2a3f..20f7c9f 100644
--- a/system/OpenglSystemCommon/ProcessPipe.h
+++ b/system/OpenglSystemCommon/ProcessPipe.h
@@ -34,3 +34,4 @@
struct renderControl_encoder_context_t;
extern bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc);
+extern uint64_t getPuid();
diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp
index 601ad9d..7d140a9 100644
--- a/system/egl/egl.cpp
+++ b/system/egl/egl.cpp
@@ -14,6 +14,11 @@
* limitations under the License.
*/
+#ifdef GFXSTREAM
+#include <atomic>
+#include <time.h>
+#endif
+
#include <assert.h>
#include "HostConnection.h"
#include "ThreadInfo.h"
@@ -49,6 +54,11 @@
#include <poll.h>
#endif // VIRTIO_GPU
+#ifdef GFXSTREAM
+#include "android/base/Tracing.h"
+#endif
+#include <cutils/trace.h>
+
#if PLATFORM_SDK_VERSION < 18
#define override
#endif
@@ -611,6 +621,68 @@
fd_out);
}
+uint64_t currGuestTimeNs() {
+ struct timespec ts;
+#ifdef __APPLE__
+ clock_gettime(CLOCK_REALTIME, &ts);
+#else
+ clock_gettime(CLOCK_BOOTTIME, &ts);
+#endif
+ uint64_t res = (uint64_t)(ts.tv_sec * 1000000000ULL + ts.tv_nsec);
+ return res;
+}
+
+struct FrameTracingState {
+ uint32_t frameNumber = 0;
+ bool tracingEnabled = false;
+ void onSwapBuffersSuccesful(ExtendedRCEncoderContext* rcEnc) {
+#ifdef GFXSTREAM
+ bool current = android::base::isTracingEnabled();
+ // edge trigger
+ if (android::base::isTracingEnabled() && !tracingEnabled) {
+ if (rcEnc->hasHostSideTracing()) {
+ rcEnc->rcSetTracingForPuid(rcEnc, getPuid(), 1, currGuestTimeNs());
+ }
+ }
+ if (!android::base::isTracingEnabled() && tracingEnabled) {
+ if (rcEnc->hasHostSideTracing()) {
+ rcEnc->rcSetTracingForPuid(rcEnc, getPuid(), 0, currGuestTimeNs());
+ }
+ }
+ tracingEnabled = android::base::isTracingEnabled();
+#endif
+ ++frameNumber;
+ }
+};
+
+static FrameTracingState sFrameTracingState;
+
+static void sFlushBufferAndCreateFence(
+ HostConnection* hostCon, ExtendedRCEncoderContext* rcEnc, uint32_t rcSurface, uint32_t frameNumber, int* presentFenceFd) {
+ atrace_int(ATRACE_TAG_GRAPHICS, "gfxstreamFrameNumber", (int32_t)frameNumber);
+
+ if (rcEnc->hasHostSideTracing()) {
+ rcEnc->rcFlushWindowColorBufferAsyncWithFrameNumber(rcEnc, rcSurface, frameNumber);
+ } else {
+ rcEnc->rcFlushWindowColorBufferAsync(rcEnc, rcSurface);
+ }
+
+ if (rcEnc->hasVirtioGpuNativeSync()) {
+ createNativeSync_virtioGpu(EGL_SYNC_NATIVE_FENCE_ANDROID,
+ NULL /* empty attrib list */,
+ 0 /* 0 attrib count */,
+ true /* destroy when signaled. this is host-only
+ and there will only be one waiter */,
+ -1 /* we want a new fd */,
+ presentFenceFd);
+ } else if (rcEnc->hasNativeSync()) {
+ createGoldfishOpenGLNativeSync(presentFenceFd);
+ } else {
+ // equivalent to glFinish if no native sync
+ eglWaitClient();
+ }
+}
+
EGLBoolean egl_window_surface_t::swapBuffers()
{
@@ -645,23 +717,9 @@
eglWaitClient();
nativeWindow->queueBuffer(nativeWindow, buffer);
#else
- if (rcEnc->hasVirtioGpuNativeSync()) {
- rcEnc->rcFlushWindowColorBufferAsync(rcEnc, rcSurface);
- createNativeSync_virtioGpu(EGL_SYNC_NATIVE_FENCE_ANDROID,
- NULL /* empty attrib list */,
- 0 /* 0 attrib count */,
- true /* destroy when signaled. this is host-only
- and there will only be one waiter */,
- -1 /* we want a new fd */,
- &presentFenceFd);
- } else if (rcEnc->hasNativeSync()) {
- rcEnc->rcFlushWindowColorBufferAsync(rcEnc, rcSurface);
- createGoldfishOpenGLNativeSync(&presentFenceFd);
- } else {
- rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
- // equivalent to glFinish if no native sync
- eglWaitClient();
- }
+ sFlushBufferAndCreateFence(
+ hostCon, rcEnc, rcSurface,
+ sFrameTracingState.frameNumber, &presentFenceFd);
DPRINT("queueBuffer with fence %d", presentFenceFd);
nativeWindow->queueBuffer(nativeWindow, buffer, presentFenceFd);
@@ -694,6 +752,7 @@
setWidth(buffer->width);
setHeight(buffer->height);
+ sFrameTracingState.onSwapBuffersSuccesful(rcEnc);
return EGL_TRUE;
}
diff --git a/system/renderControl_enc/renderControl_client_context.cpp b/system/renderControl_enc/renderControl_client_context.cpp
index 5b1f14e..5804699 100644
--- a/system/renderControl_enc/renderControl_client_context.cpp
+++ b/system/renderControl_enc/renderControl_client_context.cpp
@@ -65,6 +65,8 @@
rcMapGpaToBufferHandle = (rcMapGpaToBufferHandle_client_proc_t) getProc("rcMapGpaToBufferHandle", userData);
rcCreateBuffer2 = (rcCreateBuffer2_client_proc_t) getProc("rcCreateBuffer2", userData);
rcMapGpaToBufferHandle2 = (rcMapGpaToBufferHandle2_client_proc_t) getProc("rcMapGpaToBufferHandle2", userData);
+ rcFlushWindowColorBufferAsyncWithFrameNumber = (rcFlushWindowColorBufferAsyncWithFrameNumber_client_proc_t) getProc("rcFlushWindowColorBufferAsyncWithFrameNumber", userData);
+ rcSetTracingForPuid = (rcSetTracingForPuid_client_proc_t) getProc("rcSetTracingForPuid", userData);
return 0;
}
diff --git a/system/renderControl_enc/renderControl_client_context.h b/system/renderControl_enc/renderControl_client_context.h
index 2032a32..786a9cd 100644
--- a/system/renderControl_enc/renderControl_client_context.h
+++ b/system/renderControl_enc/renderControl_client_context.h
@@ -65,6 +65,8 @@
rcMapGpaToBufferHandle_client_proc_t rcMapGpaToBufferHandle;
rcCreateBuffer2_client_proc_t rcCreateBuffer2;
rcMapGpaToBufferHandle2_client_proc_t rcMapGpaToBufferHandle2;
+ rcFlushWindowColorBufferAsyncWithFrameNumber_client_proc_t rcFlushWindowColorBufferAsyncWithFrameNumber;
+ rcSetTracingForPuid_client_proc_t rcSetTracingForPuid;
virtual ~renderControl_client_context_t() {}
typedef renderControl_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
diff --git a/system/renderControl_enc/renderControl_client_proc.h b/system/renderControl_enc/renderControl_client_proc.h
index c0b9a7f..92b6b60 100644
--- a/system/renderControl_enc/renderControl_client_proc.h
+++ b/system/renderControl_enc/renderControl_client_proc.h
@@ -67,6 +67,8 @@
typedef int (renderControl_APIENTRY *rcMapGpaToBufferHandle_client_proc_t) (void * ctx, uint32_t, uint64_t);
typedef uint32_t (renderControl_APIENTRY *rcCreateBuffer2_client_proc_t) (void * ctx, uint64_t, uint32_t);
typedef int (renderControl_APIENTRY *rcMapGpaToBufferHandle2_client_proc_t) (void * ctx, uint32_t, uint64_t, uint64_t);
+typedef void (renderControl_APIENTRY *rcFlushWindowColorBufferAsyncWithFrameNumber_client_proc_t) (void * ctx, uint32_t, uint32_t);
+typedef void (renderControl_APIENTRY *rcSetTracingForPuid_client_proc_t) (void * ctx, uint64_t, uint32_t, uint64_t);
#endif
diff --git a/system/renderControl_enc/renderControl_enc.cpp b/system/renderControl_enc/renderControl_enc.cpp
index 6b2680c..d3abbd8 100644
--- a/system/renderControl_enc/renderControl_enc.cpp
+++ b/system/renderControl_enc/renderControl_enc.cpp
@@ -2188,6 +2188,61 @@
return retval;
}
+void rcFlushWindowColorBufferAsyncWithFrameNumber_enc(void *self , uint32_t windowSurface, uint32_t frameNumber)
+{
+ AEMU_SCOPED_TRACE("rcFlushWindowColorBufferAsyncWithFrameNumber encode");
+
+ renderControl_encoder_context_t *ctx = (renderControl_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;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_rcFlushWindowColorBufferAsyncWithFrameNumber;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &windowSurface, 4); ptr += 4;
+ memcpy(ptr, &frameNumber, 4); ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+}
+
+void rcSetTracingForPuid_enc(void *self , uint64_t puid, uint32_t enable, uint64_t guestTime)
+{
+ AEMU_SCOPED_TRACE("rcSetTracingForPuid encode");
+
+ renderControl_encoder_context_t *ctx = (renderControl_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 + 8 + 4 + 8;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_rcSetTracingForPuid;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &puid, 8); ptr += 8;
+ memcpy(ptr, &enable, 4); ptr += 4;
+ memcpy(ptr, &guestTime, 8); ptr += 8;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+}
+
} // namespace
renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator)
@@ -2250,5 +2305,7 @@
this->rcMapGpaToBufferHandle = &rcMapGpaToBufferHandle_enc;
this->rcCreateBuffer2 = &rcCreateBuffer2_enc;
this->rcMapGpaToBufferHandle2 = &rcMapGpaToBufferHandle2_enc;
+ this->rcFlushWindowColorBufferAsyncWithFrameNumber = &rcFlushWindowColorBufferAsyncWithFrameNumber_enc;
+ this->rcSetTracingForPuid = &rcSetTracingForPuid_enc;
}
diff --git a/system/renderControl_enc/renderControl_entry.cpp b/system/renderControl_enc/renderControl_entry.cpp
index 0ea37d6..5f695ab 100644
--- a/system/renderControl_enc/renderControl_entry.cpp
+++ b/system/renderControl_enc/renderControl_entry.cpp
@@ -60,6 +60,8 @@
int rcMapGpaToBufferHandle(uint32_t bufferHandle, uint64_t gpa);
uint32_t rcCreateBuffer2(uint64_t size, uint32_t memoryProperty);
int rcMapGpaToBufferHandle2(uint32_t bufferHandle, uint64_t gpa, uint64_t size);
+ void rcFlushWindowColorBufferAsyncWithFrameNumber(uint32_t windowSurface, uint32_t frameNumber);
+ void rcSetTracingForPuid(uint64_t puid, uint32_t enable, uint64_t guestTime);
};
#ifndef GET_CONTEXT
@@ -398,3 +400,15 @@
return ctx->rcMapGpaToBufferHandle2(ctx, bufferHandle, gpa, size);
}
+void rcFlushWindowColorBufferAsyncWithFrameNumber(uint32_t windowSurface, uint32_t frameNumber)
+{
+ GET_CONTEXT;
+ ctx->rcFlushWindowColorBufferAsyncWithFrameNumber(ctx, windowSurface, frameNumber);
+}
+
+void rcSetTracingForPuid(uint64_t puid, uint32_t enable, uint64_t guestTime)
+{
+ GET_CONTEXT;
+ ctx->rcSetTracingForPuid(ctx, puid, enable, guestTime);
+}
+
diff --git a/system/renderControl_enc/renderControl_ftable.h b/system/renderControl_enc/renderControl_ftable.h
index 247a0bd..38dbc85 100644
--- a/system/renderControl_enc/renderControl_ftable.h
+++ b/system/renderControl_enc/renderControl_ftable.h
@@ -63,6 +63,8 @@
{"rcMapGpaToBufferHandle", (void*)rcMapGpaToBufferHandle},
{"rcCreateBuffer2", (void*)rcCreateBuffer2},
{"rcMapGpaToBufferHandle2", (void*)rcMapGpaToBufferHandle2},
+ {"rcFlushWindowColorBufferAsyncWithFrameNumber", (void*)rcFlushWindowColorBufferAsyncWithFrameNumber},
+ {"rcSetTracingForPuid", (void*)rcSetTracingForPuid},
};
static const int renderControl_num_funcs = sizeof(renderControl_funcs_by_name) / sizeof(struct _renderControl_funcs_by_name);
diff --git a/system/renderControl_enc/renderControl_opcodes.h b/system/renderControl_enc/renderControl_opcodes.h
index 16c0214..5b8844e 100644
--- a/system/renderControl_enc/renderControl_opcodes.h
+++ b/system/renderControl_enc/renderControl_opcodes.h
@@ -58,7 +58,9 @@
#define OP_rcMapGpaToBufferHandle 10052
#define OP_rcCreateBuffer2 10053
#define OP_rcMapGpaToBufferHandle2 10054
-#define OP_last 10055
+#define OP_rcFlushWindowColorBufferAsyncWithFrameNumber 10055
+#define OP_rcSetTracingForPuid 10056
+#define OP_last 10057
#endif