aboutsummaryrefslogtreecommitdiff
path: root/src/canvas-drm.h
blob: e5dde15cd306a5f6dcec53f1b0d41d73137d65e5 (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
//
// Copyright © 2012 Linaro Limited
//
// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
//
// glmark2 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.
//
// glmark2 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
// glmark2.  If not, see <http://www.gnu.org/licenses/>.
//
// Authors:
//  Simon Que 
//  Jesse Barker
//
#ifndef GLMARK2_CANVAS_DRM_H_
#define GLMARK2_CANVAS_DRM_H_

#include <cstring>
#include <gbm.h>
#include <drm.h>
#include <xf86drm.h>
#include <xf86drmMode.h>

#include "canvas.h"
#include "egl-state.h"

struct DRMFBState
{
    int fd;
    gbm_bo* bo;
    uint32_t fb_id;
};

class DRMState
{
    static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
                                  unsigned int usec, void* data);
    static void fb_destroy_callback(gbm_bo* bo, void* data);
    DRMFBState* fb_get_from_bo(gbm_bo* bo);
    bool init_gbm();
    int fd_;
    drmModeRes* resources_;
    drmModeConnector* connector_;
    drmModeEncoder* encoder_;
    drmModeCrtcPtr crtc_;
    drmModeModeInfo* mode_;
    gbm_device* dev_;
    gbm_surface* surface_;
    gbm_bo* bo_;
    DRMFBState* fb_;

public:
    DRMState() :
        fd_(0),
        resources_(0),
        connector_(0),
        encoder_(0),
        mode_(0),
        dev_(0),
        surface_(0),
        bo_(0),
        fb_(0) {}
    ~DRMState() { cleanup(); }
    void cleanup();
    bool init();
    bool reset();
    void do_flip();
    gbm_device* device() const { return dev_; }
    gbm_surface* surface() const { return surface_; }
    unsigned int mode_width() const
    { 
        if (mode_) {
            return mode_->hdisplay;
        }
        return 0;
    }
    unsigned int mode_height() const
    {
        if (mode_) {
            return mode_->vdisplay;
        }
        return 0;
    }
};

/**
 * Canvas for direct rendering with EGL.
 */
class CanvasDRM: public Canvas
{
public:
    CanvasDRM(int width, int height) :
        Canvas(width, height) {}
    ~CanvasDRM();

    virtual bool init();
    virtual bool reset();
    virtual void visible(bool visible);
    virtual void clear();
    virtual void update();
    virtual void print_info();
    virtual Pixel read_pixel(int x, int y);
    virtual void write_to_file(std::string &filename);
    virtual bool should_quit();
    virtual void resize(int width, int height);

protected:
    virtual bool make_current();
    virtual bool reset_context();
    virtual void swap_buffers();
    virtual bool supports_gl2();

private:
    DRMState drm_;
    EGLState egl_;

    void resize_no_viewport(int width, int height);
    void init_gl_extensions();

    static void quit_handler(int signum);
    static bool should_quit_;
};

#endif