Refactor the code
* Split out classes for pixel buffer and virtual display
* Move resize handling to appropriate classes
* Use callbacks for orientation change and client resize
* Remove unnecessary locking
diff --git a/src/VirtualDisplay.cpp b/src/VirtualDisplay.cpp
new file mode 100644
index 0000000..8000f8f
--- /dev/null
+++ b/src/VirtualDisplay.cpp
@@ -0,0 +1,94 @@
+//
+// vncflinger - Copyright (C) 2017 Steve Kondik
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#define LOG_TAG "VirtualDisplay"
+#include <utils/Log.h>
+
+#include <gui/BufferQueue.h>
+#include <gui/CpuConsumer.h>
+#include <gui/IGraphicBufferConsumer.h>
+#include <gui/SurfaceComposerClient.h>
+
+#include "VirtualDisplay.h"
+
+using namespace vncflinger;
+
+VirtualDisplay::VirtualDisplay(DisplayInfo* info, uint32_t width, uint32_t height,
+ sp<CpuConsumer::FrameAvailableListener> listener) {
+ mWidth = width;
+ mHeight = height;
+
+ if (info->orientation == DISPLAY_ORIENTATION_0 || info->orientation == DISPLAY_ORIENTATION_180) {
+ mSourceRect = Rect(info->w, info->h);
+ } else {
+ mSourceRect = Rect(info->h, info->w);
+ }
+
+ Rect displayRect = getDisplayRect();
+
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&mProducer, &consumer);
+ mCpuConsumer = new CpuConsumer(consumer, 1);
+ mCpuConsumer->setName(String8("vds-to-cpu"));
+ mCpuConsumer->setDefaultBufferSize(width, height);
+ mProducer->setMaxDequeuedBufferCount(4);
+ consumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBX_8888);
+
+ mCpuConsumer->setFrameAvailableListener(listener);
+
+ mDpy = SurfaceComposerClient::createDisplay(String8("VNC-VirtualDisplay"), false /*secure*/);
+
+ SurfaceComposerClient::openGlobalTransaction();
+ SurfaceComposerClient::setDisplaySurface(mDpy, mProducer);
+
+ SurfaceComposerClient::setDisplayProjection(mDpy, 0, mSourceRect, displayRect);
+ SurfaceComposerClient::setDisplayLayerStack(mDpy, 0); // default stack
+ SurfaceComposerClient::closeGlobalTransaction();
+
+ ALOGV("Virtual display (%ux%u [viewport=%ux%u] created", width, height, displayRect.getWidth(),
+ displayRect.getHeight());
+}
+
+VirtualDisplay::~VirtualDisplay() {
+ mCpuConsumer.clear();
+ mProducer.clear();
+ SurfaceComposerClient::destroyDisplay(mDpy);
+
+ ALOGV("Virtual display destroyed");
+}
+
+Rect VirtualDisplay::getDisplayRect() {
+ uint32_t outWidth, outHeight;
+ if (mWidth > (uint32_t)((float)mWidth * aspectRatio())) {
+ // limited by narrow width; reduce height
+ outWidth = mWidth;
+ outHeight = (uint32_t)((float)mWidth * aspectRatio());
+ } else {
+ // limited by short height; restrict width
+ outHeight = mHeight;
+ outWidth = (uint32_t)((float)mHeight / aspectRatio());
+ }
+
+ // position the desktop in the viewport while preserving
+ // the source aspect ratio. we do this in case the client
+ // has resized the window and to deal with orientation
+ // changes set up by updateDisplayProjection
+ uint32_t offX, offY;
+ offX = (mWidth - outWidth) / 2;
+ offY = (mHeight - outHeight) / 2;
+ return Rect(offX, offY, offX + outWidth, offY + outHeight);
+}