aboutsummaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
authorVladimir Chtchetkine <vchtchetkine@google.com>2011-01-20 14:35:55 -0800
committerVladimir Chtchetkine <vchtchetkine@google.com>2011-01-20 14:35:55 -0800
commitac389ae4513263597dc02e4099867d5123faaa04 (patch)
tree6286373e4fe848803b263e208e21a928b7ef42ea /android
parentff926d00b2884a3b0b0b31a7f388e535dcf61ab4 (diff)
downloadexternal_qemu-ac389ae4513263597dc02e4099867d5123faaa04.zip
external_qemu-ac389ae4513263597dc02e4099867d5123faaa04.tar.gz
external_qemu-ac389ae4513263597dc02e4099867d5123faaa04.tar.bz2
Force core to send entire framebuffer on UI attachment
Change-Id: I2feb813314163b94781ffe765eb23527b6c4a0f1
Diffstat (limited to 'android')
-rw-r--r--android/display-core.c2
-rw-r--r--android/framebuffer-common.h11
-rw-r--r--android/framebuffer-core.c94
-rw-r--r--android/framebuffer-core.h5
-rw-r--r--android/framebuffer-ui.c14
-rw-r--r--android/sync-utils.c1
-rw-r--r--android/sync-utils.h2
7 files changed, 102 insertions, 27 deletions
diff --git a/android/display-core.c b/android/display-core.c
index 0b2a869..27b0706 100644
--- a/android/display-core.c
+++ b/android/display-core.c
@@ -43,7 +43,7 @@ coredisplay_fb_update(void* opaque, int x, int y, int w, int h)
{
CoreDisplay* cd = (CoreDisplay*)opaque;
if (cd->core_fb) {
- corefb_update(cd->core_fb, cd->ds, cd->fb, x, y, w, h);
+ corefb_update(cd->core_fb, cd->fb, x, y, w, h);
}
}
diff --git a/android/framebuffer-common.h b/android/framebuffer-common.h
index 95f65b6..da773b7 100644
--- a/android/framebuffer-common.h
+++ b/android/framebuffer-common.h
@@ -31,4 +31,15 @@ typedef struct FBUpdateMessage {
uint8_t rect[0];
} FBUpdateMessage;
+/* Requests the service to refresh framebuffer. */
+#define AFB_REQUEST_REFRESH 1
+
+/* Header for framebuffer requests sent from the client (UI)
+ * to the service (core).
+ */
+typedef struct FBRequestHeader {
+ /* Request type. See AFB_REQUEST_XXX for the values. */
+ uint8_t request_type;
+} FBRequestHeader;
+
#endif /* _ANDROID_FRAMEBUFFER_UI_H */
diff --git a/android/framebuffer-core.c b/android/framebuffer-core.c
index 3eb7665..89b7b46 100644
--- a/android/framebuffer-core.c
+++ b/android/framebuffer-core.c
@@ -30,6 +30,9 @@ struct CoreFramebuffer {
/* Writer used to send FB update notification messages. */
AsyncWriter fb_update_writer;
+ /* Reader used to read FB requests from the client. */
+ AsyncReader fb_req_reader;
+
/* I/O associated with this descriptor. */
LoopIo io;
@@ -47,6 +50,9 @@ struct CoreFramebuffer {
/* Socket used to communicate framebuffer updates. */
int sock;
+
+ /* Framebuffer request header. */
+ FBRequestHeader fb_req_header;
};
/* Framebuffer update notification descriptor to the core. */
@@ -140,25 +146,14 @@ fbupdatenotify_delete(FBUpdateNotify* desc)
extern void destroy_control_fb_client(void);
/*
- * Asynchronous I/O callback launched when writing framebuffer notifications
- * to the socket.
+ * Asynchronous write I/O callback launched when writing framebuffer
+ * notifications to the socket.
* Param:
- * opaque - CoreFramebuffer instance.
+ * core_fb - CoreFramebuffer instance.
*/
static void
-corefb_io_func(void* opaque, int fd, unsigned events)
+corefb_io_write(CoreFramebuffer* core_fb)
{
- CoreFramebuffer* core_fb = opaque;
-
- if (events & LOOP_IO_READ) {
- // We don't expect the UI client to write anything here, except when
- // the client gets disconnected.
- loopIo_dontWantWrite(&core_fb->io);
- loopIo_dontWantRead(&core_fb->io);
- destroy_control_fb_client();
- return;
- }
-
while (core_fb->fb_update_head != NULL) {
FBUpdateNotify* current_update = core_fb->fb_update_head;
// Lets continue writing of the current notification.
@@ -195,6 +190,66 @@ corefb_io_func(void* opaque, int fd, unsigned events)
}
}
+/*
+ * Asynchronous read I/O callback launched when reading framebuffer requests
+ * from the socket.
+ * Param:
+ * core_fb - CoreFramebuffer instance.
+ */
+static void
+corefb_io_read(CoreFramebuffer* core_fb)
+{
+ // Read the request header.
+ const AsyncStatus status =
+ asyncReader_read(&core_fb->fb_req_reader, &core_fb->io);
+ switch (status) {
+ case ASYNC_COMPLETE:
+ // Request header is received
+ switch (core_fb->fb_req_header.request_type) {
+ case AFB_REQUEST_REFRESH:
+ // Force full screen update to be sent
+ corefb_update(core_fb, core_fb->fb,
+ 0, 0, core_fb->fb->width, core_fb->fb->height);
+ break;
+ default:
+ derror("Unknown framebuffer request %d\n",
+ core_fb->fb_req_header.request_type);
+ break;
+ }
+ core_fb->fb_req_header.request_type = -1;
+ asyncReader_init(&core_fb->fb_req_reader, &core_fb->fb_req_header,
+ sizeof(core_fb->fb_req_header), &core_fb->io);
+ break;
+ case ASYNC_ERROR:
+ loopIo_dontWantRead(&core_fb->io);
+ if (errno == ECONNRESET) {
+ // UI has exited. We need to destroy framebuffer service.
+ destroy_control_fb_client();
+ }
+ break;
+
+ case ASYNC_NEED_MORE:
+ // Transfer will eventually come back into this routine.
+ return;
+ }
+}
+
+/*
+ * Asynchronous I/O callback launched when writing framebuffer notifications
+ * to the socket.
+ * Param:
+ * opaque - CoreFramebuffer instance.
+ */
+static void
+corefb_io_func(void* opaque, int fd, unsigned events)
+{
+ if (events & LOOP_IO_READ) {
+ corefb_io_read((CoreFramebuffer*)opaque);
+ } else if (events & LOOP_IO_WRITE) {
+ corefb_io_write((CoreFramebuffer*)opaque);
+ }
+}
+
CoreFramebuffer*
corefb_create(int sock, const char* protocol, QFrameBuffer* fb)
{
@@ -203,13 +258,12 @@ corefb_create(int sock, const char* protocol, QFrameBuffer* fb)
ANEW0(ret);
ret->sock = sock;
ret->looper = looper_newCore();
- loopIo_init(&ret->io, ret->looper, sock, corefb_io_func, ret);
- // Since we're overriding the read callback with our looper's I/O routine,
- // we need to have set our read callback here to monitor disconnections.
- loopIo_wantRead(&ret->io);
ret->fb = fb;
ret->fb_update_head = NULL;
ret->fb_update_tail = NULL;
+ loopIo_init(&ret->io, ret->looper, sock, corefb_io_func, ret);
+ asyncReader_init(&ret->fb_req_reader, &ret->fb_req_header,
+ sizeof(ret->fb_req_header), &ret->io);
return ret;
}
@@ -234,7 +288,7 @@ corefb_destroy(CoreFramebuffer* core_fb)
}
void
-corefb_update(CoreFramebuffer* core_fb, struct DisplayState* ds,
+corefb_update(CoreFramebuffer* core_fb,
struct QFrameBuffer* fb, int x, int y, int w, int h)
{
AsyncStatus status;
diff --git a/android/framebuffer-core.h b/android/framebuffer-core.h
index fd4af52..773c248 100644
--- a/android/framebuffer-core.h
+++ b/android/framebuffer-core.h
@@ -46,12 +46,11 @@ void corefb_destroy(CoreFramebuffer* core_fb);
* Notifies framebuffer client about changes in framebuffer.
* Param:
* core_fb - Framebuffer service descriptor created with corefb_create
- * ds - Display state for the framebuffer.
* fb Framebuffer containing pixels.
* x, y, w, and h identify the rectangle that has benn changed.
*/
-void corefb_update(CoreFramebuffer* core_fb, struct DisplayState* ds,
- struct QFrameBuffer* fb, int x, int y, int w, int h);
+void corefb_update(CoreFramebuffer* core_fb, struct QFrameBuffer* fb,
+ int x, int y, int w, int h);
/*
* Gets number of bits used to encode a single pixel.
diff --git a/android/framebuffer-ui.c b/android/framebuffer-ui.c
index 5202381..0ae109f 100644
--- a/android/framebuffer-ui.c
+++ b/android/framebuffer-ui.c
@@ -19,6 +19,7 @@
#include "android/framebuffer-ui.h"
#include "android/utils/system.h"
#include "android/utils/debug.h"
+#include "android/sync-utils.h"
#define PANIC(...) do { fprintf(stderr, __VA_ARGS__); \
exit(1); \
@@ -247,7 +248,18 @@ clientfb_create(SockAddress* console_socket,
_client_fb.core_connection = NULL;
return NULL;
}
-
+ {
+ // Force the core to send us entire framebuffer now, when we're prepared
+ // to receive it.
+ FBRequestHeader hd;
+ SyncSocket* sk = syncsocket_init(_client_fb.sock);
+
+ hd.request_type = AFB_REQUEST_REFRESH;
+ syncsocket_start_write(sk);
+ syncsocket_write(sk, &hd, sizeof(hd), 500);
+ syncsocket_stop_write(sk);
+ syncsocket_free(sk);
+ }
fprintf(stdout, "Framebuffer %s is now attached to the core %s\n",
protocol, sock_address_to_string(console_socket));
diff --git a/android/sync-utils.c b/android/sync-utils.c
index 32c803c..6d3cea6 100644
--- a/android/sync-utils.c
+++ b/android/sync-utils.c
@@ -113,7 +113,6 @@ void
syncsocket_free(SyncSocket* ssocket)
{
if (ssocket != NULL) {
- syncsocket_close(ssocket);
if (ssocket->iolooper != NULL) {
iolooper_free(ssocket->iolooper);
}
diff --git a/android/sync-utils.h b/android/sync-utils.h
index 110a143..1dcf649 100644
--- a/android/sync-utils.h
+++ b/android/sync-utils.h
@@ -43,7 +43,7 @@ SyncSocket* syncsocket_connect(int fd, SockAddress* sockaddr, int timeout);
* Note: this routine will explicitly call socket_set_nonblock on the fd passed
* to this routine.
* Param:
- * fd - File descriptor for the already connected.
+ * fd - File descriptor for the already connected socket.
* Return:
* Initialized SyncSocket descriptor on success, or NULL on failure.
*/