framebuffer_service.c revision 154b7d7de4071ed73cde81eef3af47d1a24d7c6b
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23414ff7d98ac8d7610a26206335954ad15f43f3acDavid 'Digit' Turner#include "fdevent.h"
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h"
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/fb.h>
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h>
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mman.h>
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* TODO:
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** - sync with vsync to avoid tearing
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
33154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin/* This version number defines the format of the fbinfo struct.
34154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin   It must match versioning in ddms where this data is consumed. */
35154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin#define DDMS_RAWIMAGE_VERSION 1
36154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavinstruct fbinfo {
37154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int version;
38154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int bpp;
39154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int size;
40154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int width;
41154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int height;
42154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int red_offset;
43154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int red_length;
44154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int blue_offset;
45154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int blue_length;
46154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int green_offset;
47154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int green_length;
48154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int alpha_offset;
49154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int alpha_length;
50154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin} __attribute__((packed));
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid framebuffer_service(int fd, void *cookie)
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct fb_var_screeninfo vinfo;
5504bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    int fb, offset;
5604bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    char x[256];
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    struct fbinfo fbinfo;
5904bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    unsigned i, bytespp;
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fb = open("/dev/graphics/fb0", O_RDONLY);
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fb < 0) goto done;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) goto done;
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fcntl(fb, F_SETFD, FD_CLOEXEC);
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
6704bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    bytespp = vinfo.bits_per_pixel / 8;
6804bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
69154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.version = DDMS_RAWIMAGE_VERSION;
70154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.bpp = vinfo.bits_per_pixel;
71154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.size = vinfo.xres * vinfo.yres * bytespp;
72154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.width = vinfo.xres;
73154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.height = vinfo.yres;
74154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.red_offset = vinfo.red.offset;
75154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.red_length = vinfo.red.length;
76154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.green_offset = vinfo.green.offset;
77154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.green_length = vinfo.green.length;
78154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.blue_offset = vinfo.blue.offset;
79154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.blue_length = vinfo.blue.length;
80154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.alpha_offset = vinfo.transp.offset;
81154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.alpha_length = vinfo.transp.length;
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
8304bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    /* HACK: for several of our 3d cores a specific alignment
8404bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin     * is required so the start of the fb may not be an integer number of lines
8504bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin     * from the base.  As a result we are storing the additional offset in
8604bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin     * xoffset. This is not the correct usage for xoffset, it should be added
8704bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin     * to each line, not just once at the beginning */
8804bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    offset = vinfo.xoffset * bytespp;
8904bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
9004bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    offset += vinfo.xres * vinfo.yoffset * bytespp;
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
92154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
9404bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin    lseek(fb, offset, SEEK_SET);
95154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    for(i = 0; i < fbinfo.size; i += 256) {
9604bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin      if(readx(fb, &x, 256)) goto done;
9704bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin      if(writex(fd, &x, 256)) goto done;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    if(readx(fb, &x, fbinfo.size % 256)) goto done;
101154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    if(writex(fd, &x, fbinfo.size % 256)) goto done;
10204bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone:
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fb >= 0) close(fb);
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close(fd);
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
107