summaryrefslogtreecommitdiff
path: root/stream-servers/FbConfig.h
blob: 25211313201a5f24b65ca4726aeadf6c9c429374 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _LIBRENDER_FB_CONFIG_H
#define _LIBRENDER_FB_CONFIG_H

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>

#include <stddef.h>

// A class used to model a guest EGL config.
// This really wraps a host EGLConfig handle, and provides a few cached
// attributes that can be retrieved through direct accessors, like
// getDepthSize().
//
// Each FbConfig is identified by a unique id which is its index in
// an FbConfigList instance (as declared below). It is not related to
// the host EGLConfig value or its EGL_CONFIG_ID.
//
// One doesn't create an FbConfig instance. Instead, create and initialize
// an FbConfigList from the host EGLDisplay, and use its size() and get()
// methods to access it.
class FbConfig {
public:
    // Destructor
    ~FbConfig();

    // Retrieve host EGLConfig.
    EGLConfig getEglConfig() const { return mEglConfig; }

    // Get depth size in bits.
    GLuint getDepthSize() const { return getAttribValue(0); }

    // Get stencil size in bits.
    GLuint getStencilSize() const { return getAttribValue(1); }

    // Get renderable type mask.
    GLuint getRenderableType() const { return getAttribValue(2); }

    // Get surface type mask.
    GLuint getSurfaceType() const { return getAttribValue(3); }

    // Get the EGL_CONFIG_ID value. This is the same as the one of the
    // underlying host EGLConfig handle.
    GLint getConfigId() const { return (GLint)getAttribValue(4); }

private:
    FbConfig();
    FbConfig(FbConfig& other);

    explicit FbConfig(EGLConfig hostConfig, EGLDisplay hostDisplay);

    friend class FbConfigList;

    GLuint getAttribValue(int n) const {
        return mAttribValues ? mAttribValues[n] : 0U;
    }

    EGLConfig mEglConfig;
    GLint* mAttribValues;
};

// A class to model the list of FbConfig for a given EGLDisplay, this is
// built from the list of host EGLConfig handles, filtered to only accept
// configs that are useful by the rendering library (e.g. they must support
// PBuffers and RGB pixel values).
//
// Usage is the following:
//
// 1) Create new instance by passing host EGLDisplay value.
//
// 2) Call empty() to check that the list is not empty, which would indicate
//    an error during creation.
//
// 3) FbConfig instances are identified by numbers in 0..(N-1) range, where
//    N is the result of the size() method.
//
// 4) Convert an FbConfig id into an FbConfig instance with get().
//
// 5) Use getPackInfo() and packConfigs() to retrieve information about
//    available configs to the guest.
class FbConfigList {
public:
    // Create a new list of FbConfig instance, by querying all compatible
    // host configs from |display|. A compatible config is one that supports
    // Pbuffers and RGB pixel values.
    //
    // After construction, call empty() to check if there are items.
    // An empty list means there was an error during construction.
    explicit FbConfigList(EGLDisplay display);

    // Destructor.
    ~FbConfigList();

    // Return true iff the list is empty. true means there was an error
    // during construction.
    bool empty() const { return mCount == 0; }

    // Return the number of FbConfig instances in the list.
    // Each instance is identified by a number from 0 to N-1,
    // where N is the result of this function.
    size_t size() const { return static_cast<size_t>(mCount); }

    // Retrieve the FbConfig instance associated with |guestId|,
    // which must be an integer between 0 and |size() - 1|. Returns
    // NULL in case of failure.
    const FbConfig* get(int guestId) const {
        if (guestId >= 0 && guestId < mCount) {
            return mConfigs[guestId];
        } else {
            return NULL;
        }
    }

    // Use |attribs| a list of EGL attribute name/values terminated by
    // EGL_NONE, to select a set of matching FbConfig instances.
    //
    // On success, returns the number of matching instances.
    // If |configs| is not NULL, it will be populated with the guest IDs
    // of the matched FbConfig instances.
    //
    // |configsSize| is the number of entries in the |configs| array. The
    // function will never write more than |configsSize| entries into
    // |configsSize|.
    EGLint chooseConfig(const EGLint* attribs,
                        EGLint* configs,
                        EGLint configsSize) const;

    // Retrieve information that can be sent to the guest before packed
    // config list information. If |numConfigs| is NULL, then |*numConfigs|
    // will be set on return to the number of config instances.
    // If |numAttribs| is not NULL, then |*numAttribs| will be set on return
    // to the number of attribute values cached by each FbConfig instance.
    void getPackInfo(EGLint* mumConfigs, EGLint* numAttribs) const;

    // Write the full list information into an array of EGLuint items.
    // |buffer| is the output buffer that will receive the data.
    // |bufferByteSize| is teh buffer size in bytes.
    // On success, this returns
    EGLint packConfigs(GLuint bufferByteSize, GLuint* buffer) const;

private:
    FbConfigList(const FbConfigList& other) = delete;

    int mCount = 0;
    FbConfig** mConfigs = nullptr;
    EGLDisplay mDisplay = 0;
};

#endif  // _LIBRENDER_FB_CONFIG_H