diff --git a/src/VNCFlinger.cpp b/src/VNCFlinger.cpp index a55b8684311549eb18e8db0e3de8c71b88eb719c..0ca27841df20cbdc474029207bf8ceb78de68618 100644 --- a/src/VNCFlinger.cpp +++ b/src/VNCFlinger.cpp @@ -57,10 +57,6 @@ status_t VNCFlinger::setup_l() { sQueue->addListener(this); - mVirtualDisplay = new VirtualDisplay(); - - mVNCBuf = new uint8_t[mWidth * mHeight * 4]; - rfbLog = VNCFlinger::rfbLogger; rfbErr = VNCFlinger::rfbLogger; @@ -71,8 +67,9 @@ status_t VNCFlinger::setup_l() { 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 @@ status_t VNCFlinger::setup_l() { 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 @@ void VNCFlinger::onEvent(const Event& event) { 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 369d2719e6d97beb504dbd2d32c1de79396d4156..7a95042d872fb52ff523cb2fd5330122b8b6b339 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 @@ bool VirtualDisplay::threadLoop() { 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 @@ status_t VirtualDisplay::setup_l() { } mBufSize = mWidth * mHeight * kGlBytesPerPixel; - + // pixel buffer for image copy mPBO = new GLuint[NUM_PBO]; glGenBuffers(NUM_PBO, mPBO); @@ -256,6 +257,9 @@ void* VirtualDisplay::processFrame_l() { 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 @@ void* VirtualDisplay::processFrame_l() { 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 @@ void* VirtualDisplay::processFrame_l() { 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 ccfb718877aa9e81fac0f5ca83086c1cdf3a9385..c215395cc7af06242149393b4f6677506e268e87 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 @@ namespace android { */ 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 @@ public: // 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 @@ private: // Process a frame received from the virtual display. void* processFrame_l(); + rfbScreenInfoPtr mVNCScreen; + uint32_t mHeight, mWidth; bool mRotate; @@ -119,6 +123,7 @@ private: // Pixel data buffers. size_t mBufSize; + uint8_t* mPixelBuf; GLuint* mPBO; unsigned int mIndex;