aboutsummaryrefslogtreecommitdiffstats
path: root/android/display-core.c
blob: 0b2a869684c02aa5e44dd01b17ea056f3c239291 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* Copyright (C) 2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** 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.
*/

/*
 * Contains extension to android display (see android/display.h|c) that is used
 * by the core to communicate display changes to the attached UI
 */

#include "android/utils/system.h"
#include "android/display-core.h"

/* Core display descriptor. */
struct CoreDisplay {
    /* Display state for this core display. */
    DisplayState*       ds;

    /* Framebuffer for this core display. */
    QFrameBuffer*       fb;

    /* Framebuffer service associated with this core display. */
    CoreFramebuffer*    core_fb;
};

/* One and only one core display instance. */
CoreDisplay core_display;

/*
 * Framebuffer calls this routine when it detects changes. This routine will
 * initiate a "push" of the framebuffer changes to the UI.
 * See QFrameBufferUpdateFunc in framebuffer.h for more info on this callback.
 */
static void
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);
    }
}

/*
 * Framebuffer callback. See QFrameBufferRotateFunc in framebuffer.h for more
 * info on this callback.
 */
static void
coredisplay_fb_rotate(void* opaque, int rotation)
{
}

/*
 * Framebuffer callback. See QFrameBufferPollFunc in framebuffer.h for more
 * info on this callback.
 */
static void
coredisplay_fb_poll(void* opaque)
{
    // This will eventually call core_display_fb_update.
    qframebuffer_check_updates();
}

/*
 * Framebuffer callback. See QFrameBufferDoneFunc in framebuffer.h for more
 * info on this callback.
 */
static void
coredisplay_fb_done(void* opaque)
{
}

void
coredisplay_init(DisplayState* ds)
{
    int format;

    core_display.ds = ds;
    /* Create and initialize framebuffer instance that will be used for core
     * display.
     */
    ANEW0(core_display.fb);
    core_display.core_fb = NULL;

    /* In the core, there is no skin to parse and the format of ds->surface
     * is determined by the -android-gui option.
     */
    format = QFRAME_BUFFER_RGB565;
    if (ds->surface->pf.bytes_per_pixel == 4)
        format = QFRAME_BUFFER_RGBX_8888;

    qframebuffer_init(core_display.fb, ds->surface->width, ds->surface->height,
                      0, format);
    qframebuffer_fifo_add(core_display.fb);
    /* Register core display as the client for the framebuffer, so we can start
     * receiving framebuffer notifications. Note that until UI connects to the
     * core all framebuffer callbacks are essentially no-ops.
     */
    qframebuffer_add_client(core_display.fb, &core_display,
                            coredisplay_fb_update, coredisplay_fb_rotate,
                            coredisplay_fb_poll, coredisplay_fb_done);
    android_display_init(ds, core_display.fb);
}

int
coredisplay_attach_fb_service(CoreFramebuffer* core_fb)
{
    if (core_display.core_fb == NULL) {
        core_display.core_fb = core_fb;
        return 0;
    } else {
        return -1;
    }
}

CoreFramebuffer*
coredisplay_detach_fb_service(void)
{
    CoreFramebuffer* ret = core_display.core_fb;
    core_display.core_fb = NULL;
    return ret;
}

QFrameBuffer*
coredisplay_get_framebuffer(void)
{
    return core_display.fb;
}