Testing updates pushed from the GL thread
diff --git a/src/VNCFlinger.cpp b/src/VNCFlinger.cpp
index a55b868..0ca2784 100644
--- a/src/VNCFlinger.cpp
+++ b/src/VNCFlinger.cpp
@@ -57,10 +57,6 @@
sQueue->addListener(this);
- mVirtualDisplay = new VirtualDisplay();
-
- mVNCBuf = new uint8_t[mWidth * mHeight * 4];
-
rfbLog = VNCFlinger::rfbLogger;
rfbErr = VNCFlinger::rfbLogger;
@@ -71,8 +67,9 @@
return NO_INIT;
}
+ mVNCBuf = new uint8_t[mWidth * mHeight * 4];
+ mVNCScreen->frameBuffer = (char *) mVNCBuf;
mVNCScreen->desktopName = "VNCFlinger";
- mVNCScreen->frameBuffer = (char *)mVNCBuf;
mVNCScreen->alwaysShared = TRUE;
mVNCScreen->httpDir = NULL;
mVNCScreen->port = VNC_PORT;
@@ -80,13 +77,16 @@
mVNCScreen->serverFormat.trueColour = true;
mVNCScreen->serverFormat.bitsPerPixel = 32;
mVNCScreen->handleEventsEagerly = true;
- mVNCScreen->deferUpdateTime = 5;
+ mVNCScreen->deferUpdateTime = 16;
rfbInitServer(mVNCScreen);
/* Mark as dirty since we haven't sent any updates at all yet. */
rfbMarkRectAsModified(mVNCScreen, 0, 0, mWidth, mHeight);
+
+ mVirtualDisplay = new VirtualDisplay(mVNCScreen);
+
return err;
}
@@ -129,11 +129,21 @@
ALOGI("Client disconnected (%zu)", mClientCount);
break;
+ /*
case EVENT_BUFFER_READY:
+ int64_t startWhenNsec, endWhenNsec;
+ startWhenNsec = systemTime(CLOCK_MONOTONIC);
+ if (event.mData == NULL) {
+ break;
+ }
+ //memcpy(mVNCBuf, (uint8_t *) event.mData, mWidth * mHeight * 4);
//mVNCScreen->frameBuffer = (char *) event.mData;
- memcpy(mVNCBuf, (uint8_t *) event.mData, mWidth * mHeight * 4);
rfbMarkRectAsModified(mVNCScreen, 0, 0, mWidth, mHeight);
+ endWhenNsec = systemTime(CLOCK_MONOTONIC);
+ ALOGV("got pixels (mark=%.3fms)",
+ (endWhenNsec - startWhenNsec) / 1000000.0);
break;
+ */
default:
ALOGE("Unhandled event: %d", event.mId);
diff --git a/src/VirtualDisplay.cpp b/src/VirtualDisplay.cpp
index 369d271..7a95042 100644
--- a/src/VirtualDisplay.cpp
+++ b/src/VirtualDisplay.cpp
@@ -23,9 +23,9 @@
#include <gui/SurfaceComposerClient.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+#include <GLES2/gl2ext.h>
#include <ui/Rect.h>
@@ -186,8 +186,9 @@
mEventCond.wait(mMutex);
ALOGD("Awake, frame available");
void* ptr = processFrame_l();
- const Event ev(EVENT_BUFFER_READY, ptr);
- mQueue->enqueue(ev);
+
+ //const Event ev(EVENT_BUFFER_READY, ptr);
+ //mQueue->enqueue(ev);
}
ALOGV("VDS thread stopping");
@@ -223,7 +224,7 @@
}
mBufSize = mWidth * mHeight * kGlBytesPerPixel;
-
+
// pixel buffer for image copy
mPBO = new GLuint[NUM_PBO];
glGenBuffers(NUM_PBO, mPBO);
@@ -256,6 +257,9 @@
mGlConsumer->updateTexImage();
mGlConsumer->getTransformMatrix(texMatrix);
+ int64_t startWhen, blitWhen, readWhen, mapWhen, memcpyWhen, markWhen;
+ startWhen = systemTime(CLOCK_MONOTONIC);
+
// The data is in an external texture, so we need to render it to the
// pbuffer to get access to RGB pixel data. We also want to flip it
// upside-down for easy conversion to a bitmap.
@@ -263,6 +267,8 @@
int height = mEglWindow.getHeight();
mExtTexProgram.blit(mExtTextureName, texMatrix, 0, 0, mWidth, mHeight, true);
+ blitWhen = systemTime(CLOCK_MONOTONIC);
+
GLenum glErr;
glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO[mIndex]);
glReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0);
@@ -271,13 +277,28 @@
return NULL;
}
- glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO[mIndex]);
+ readWhen = systemTime(CLOCK_MONOTONIC);
+
void* ptr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, mBufSize, GL_MAP_READ_BIT);
+ mapWhen = systemTime(CLOCK_MONOTONIC);
+ //memcpy(mVNCScreen->frameBuffer, ptr, mBufSize);
+ mVNCScreen->frameBuffer = (char *)ptr;
+ memcpyWhen = systemTime(CLOCK_MONOTONIC);
+ rfbMarkRectAsModified(mVNCScreen, 0, 0, mWidth, mHeight);
+ markWhen = systemTime(CLOCK_MONOTONIC);
+
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
- mIndex = (mIndex + 1) % NUM_PBO;
- return ptr;
+ ALOGV("processFrame: blit=%.3fms read=%.3fms map=%.3fms memcpy=%.3fms mark=%.3fms",
+ (blitWhen - startWhen) / 1000000.0,
+ (readWhen - blitWhen) / 1000000.0,
+ (mapWhen - readWhen) / 1000000.0,
+ (memcpyWhen - mapWhen) / 1000000.0,
+ (markWhen - memcpyWhen) / 1000000.0);
+
+ mIndex = (mIndex + 1) % NUM_PBO;
+ return mVNCScreen->frameBuffer;
}
void VirtualDisplay::release_l() {
diff --git a/src/VirtualDisplay.h b/src/VirtualDisplay.h
index ccfb718..c215395 100644
--- a/src/VirtualDisplay.h
+++ b/src/VirtualDisplay.h
@@ -27,6 +27,7 @@
#include <ui/DisplayInfo.h>
#include <utils/Thread.h>
+#include <rfb/rfb.h>
#define NUM_PBO 2
@@ -37,7 +38,8 @@
*/
class VirtualDisplay : public GLConsumer::FrameAvailableListener, Thread {
public:
- VirtualDisplay() : Thread(false),
+ VirtualDisplay(rfbScreenInfoPtr vncScreen) : Thread(false),
+ mVNCScreen(vncScreen),
mThreadResult(UNKNOWN_ERROR),
mState(UNINITIALIZED),
mIndex(0)
@@ -46,9 +48,9 @@
// Create an "input surface", similar in purpose to a MediaCodec input
// surface, that the virtual display can send buffers to. Also configures
// EGL with a pbuffer surface on the current thread.
- status_t start(const DisplayInfo& mainDpyInfo, EventQueue *queue);
+ virtual status_t start(const DisplayInfo& mainDpyInfo, EventQueue *queue);
- status_t stop();
+ virtual status_t stop();
static bool isDeviceRotated(int orientation);
@@ -79,6 +81,8 @@
// Process a frame received from the virtual display.
void* processFrame_l();
+ rfbScreenInfoPtr mVNCScreen;
+
uint32_t mHeight, mWidth;
bool mRotate;
@@ -119,6 +123,7 @@
// Pixel data buffers.
size_t mBufSize;
+ uint8_t* mPixelBuf;
GLuint* mPBO;
unsigned int mIndex;