summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kmscube/kmscube.cpp326
1 files changed, 181 insertions, 145 deletions
diff --git a/kmscube/kmscube.cpp b/kmscube/kmscube.cpp
index 97b48df..62c9d97 100644
--- a/kmscube/kmscube.cpp
+++ b/kmscube/kmscube.cpp
@@ -64,7 +64,7 @@ public:
GbmDevice(const GbmDevice& other) = delete;
GbmDevice& operator=(const GbmDevice& other) = delete;
- operator struct gbm_device*() const { return m_dev; }
+ struct gbm_device* handle() const { return m_dev; }
private:
struct gbm_device* m_dev;
@@ -75,7 +75,7 @@ class GbmSurface
public:
GbmSurface(GbmDevice& gdev, int width, int height)
{
- m_surface = gbm_surface_create(gdev, width, height,
+ m_surface = gbm_surface_create(gdev.handle(), width, height,
GBM_FORMAT_XRGB8888,
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
FAIL_IF(!m_surface, "failed to create gbm surface");
@@ -89,20 +89,29 @@ public:
GbmSurface(const GbmSurface& other) = delete;
GbmSurface& operator=(const GbmSurface& other) = delete;
- operator struct gbm_surface*() const { return m_surface; }
+ gbm_bo* lock_front_buffer()
+ {
+ return gbm_surface_lock_front_buffer(m_surface);
+ }
+
+ void release_buffer(gbm_bo *bo)
+ {
+ gbm_surface_release_buffer(m_surface, bo);
+ }
+
+ struct gbm_surface* handle() const { return m_surface; }
+
private:
struct gbm_surface* m_surface;
};
-struct GLState {
- GLState(GbmDevice& gdev)
+class EglState
+{
+public:
+ EglState(EGLNativeDisplayType display_id)
{
- EGLint major, minor, n;
- GLuint vertex_shader, fragment_shader;
- GLint ret;
EGLBoolean b;
-
-#include "cube.h"
+ EGLint major, minor, n;
static const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
@@ -119,41 +128,7 @@ struct GLState {
EGL_NONE
};
- static const char *vertex_shader_source =
- "uniform mat4 modelviewMatrix; \n"
- "uniform mat4 modelviewprojectionMatrix;\n"
- "uniform mat3 normalMatrix; \n"
- " \n"
- "attribute vec4 in_position; \n"
- "attribute vec3 in_normal; \n"
- "attribute vec4 in_color; \n"
- "\n"
- "vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0);\n"
- " \n"
- "varying vec4 vVaryingColor; \n"
- " \n"
- "void main() \n"
- "{ \n"
- " gl_Position = modelviewprojectionMatrix * in_position;\n"
- " vec3 vEyeNormal = normalMatrix * in_normal;\n"
- " vec4 vPosition4 = modelviewMatrix * in_position;\n"
- " vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
- " vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
- " float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
- " vVaryingColor = vec4(diff * in_color.rgb, 1.0);\n"
- "} \n";
-
- static const char *fragment_shader_source =
- "precision mediump float; \n"
- " \n"
- "varying vec4 vVaryingColor; \n"
- " \n"
- "void main() \n"
- "{ \n"
- " gl_FragColor = vVaryingColor; \n"
- "} \n";
-
- m_display = eglGetDisplay(gdev);
+ m_display = eglGetDisplay(display_id);
FAIL_IF(!m_display, "failed to get egl display");
b = eglInitialize(m_display, &major, &minor);
@@ -192,6 +167,68 @@ struct GLState {
FAIL_IF(!m_context, "failed to create context");
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, m_context);
+ }
+
+ ~EglState()
+ {
+ eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(m_display);
+ }
+
+ EGLDisplay display() const { return m_display; }
+ EGLConfig config() const { return m_config; }
+ EGLContext context() const { return m_context; }
+
+private:
+ EGLDisplay m_display;
+ EGLConfig m_config;
+ EGLContext m_context;
+};
+
+class GlScene
+{
+public:
+ GlScene()
+ {
+ GLuint vertex_shader, fragment_shader;
+ GLint ret;
+
+#include "cube.h"
+
+ static const char *vertex_shader_source =
+ "uniform mat4 modelviewMatrix; \n"
+ "uniform mat4 modelviewprojectionMatrix;\n"
+ "uniform mat3 normalMatrix; \n"
+ " \n"
+ "attribute vec4 in_position; \n"
+ "attribute vec3 in_normal; \n"
+ "attribute vec4 in_color; \n"
+ "\n"
+ "vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0);\n"
+ " \n"
+ "varying vec4 vVaryingColor; \n"
+ " \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = modelviewprojectionMatrix * in_position;\n"
+ " vec3 vEyeNormal = normalMatrix * in_normal;\n"
+ " vec4 vPosition4 = modelviewMatrix * in_position;\n"
+ " vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
+ " vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
+ " float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
+ " vVaryingColor = vec4(diff * in_color.rgb, 1.0);\n"
+ "} \n";
+
+ static const char *fragment_shader_source =
+ "precision mediump float; \n"
+ " \n"
+ "varying vec4 vVaryingColor; \n"
+ " \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vVaryingColor; \n"
+ "} \n";
+
if (s_verbose) {
printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
@@ -257,62 +294,97 @@ struct GLState {
glEnableVertexAttribArray(2);
}
- ~GLState()
+ GlScene(const GlScene& other) = delete;
+ GlScene& operator=(const GlScene& other) = delete;
+
+ void set_viewport(uint32_t width, uint32_t height)
{
- eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglTerminate(m_display);
+ m_width = width;
+ m_height = height;
}
- GLState(const GLState& other) = delete;
- GLState& operator=(const GLState& other) = delete;
+ void draw(uint32_t framenum)
+ {
+ glViewport(0, 0, m_width, m_height);
- EGLDisplay display() const { return m_display; }
- EGLConfig config() const { return m_config; }
- EGLContext context() const { return m_context; }
+ glClearColor(0.5, 0.5, 0.5, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
- GLint modelviewmatrix() const { return m_modelviewmatrix; }
- GLint modelviewprojectionmatrix() const { return m_modelviewprojectionmatrix; }
- GLint normalmatrix() const { return m_normalmatrix; }
+ ESMatrix modelview;
+
+ esMatrixLoadIdentity(&modelview);
+ esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
+ esRotate(&modelview, 45.0f + (0.75f * framenum), 1.0f, 0.0f, 0.0f);
+ esRotate(&modelview, 45.0f - (0.5f * framenum), 0.0f, 1.0f, 0.0f);
+ esRotate(&modelview, 10.0f + (0.45f * framenum), 0.0f, 0.0f, 1.0f);
+
+ GLfloat aspect = (float)m_height / m_width;
+
+ ESMatrix projection;
+ esMatrixLoadIdentity(&projection);
+ esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);
+
+ ESMatrix modelviewprojection;
+ esMatrixLoadIdentity(&modelviewprojection);
+ esMatrixMultiply(&modelviewprojection, &modelview, &projection);
+
+ float normal[9];
+ normal[0] = modelview.m[0][0];
+ normal[1] = modelview.m[0][1];
+ normal[2] = modelview.m[0][2];
+ normal[3] = modelview.m[1][0];
+ normal[4] = modelview.m[1][1];
+ normal[5] = modelview.m[1][2];
+ normal[6] = modelview.m[2][0];
+ normal[7] = modelview.m[2][1];
+ normal[8] = modelview.m[2][2];
+
+ glUniformMatrix4fv(m_modelviewmatrix, 1, GL_FALSE, &modelview.m[0][0]);
+ glUniformMatrix4fv(m_modelviewprojectionmatrix, 1, GL_FALSE, &modelviewprojection.m[0][0]);
+ glUniformMatrix3fv(m_normalmatrix, 1, GL_FALSE, normal);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
+ glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
+ glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
+ glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
+ glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
+ }
private:
- EGLDisplay m_display;
- EGLConfig m_config;
- EGLContext m_context;
GLint m_modelviewmatrix, m_modelviewprojectionmatrix, m_normalmatrix;
+
+ uint32_t m_width;
+ uint32_t m_height;
};
-struct Surface
+class GbmEglSurface
{
- Surface(Card& card, GbmDevice& gdev, const GLState& gl, int width, int height)
- : card(card), gdev(gdev), gl(gl), gsurface(gdev, width, height), m_width(width), m_height(height),
+public:
+ GbmEglSurface(Card& card, GbmDevice& gdev, const EglState& egl, int width, int height)
+ : card(card), gdev(gdev), egl(egl), m_width(width), m_height(height),
bo_prev(0), bo_next(0)
{
- esurface = eglCreateWindowSurface(gl.display(), gl.config(), gsurface, NULL);
+ gsurface = unique_ptr<GbmSurface>(new GbmSurface(gdev, width, height));
+ esurface = eglCreateWindowSurface(egl.display(), egl.config(), gsurface->handle(), NULL);
FAIL_IF(esurface == EGL_NO_SURFACE, "failed to create egl surface");
}
- ~Surface()
+ ~GbmEglSurface()
{
if (bo_next)
- gbm_surface_release_buffer(gsurface, bo_next);
- eglDestroySurface(gl.display(), esurface);
+ gsurface->release_buffer(bo_next);
+ eglDestroySurface(egl.display(), esurface);
}
void make_current()
{
- eglMakeCurrent(gl.display(), esurface, esurface, gl.context());
- glViewport(0, 0, m_width, m_height);
- }
-
- void clear()
- {
- glClearColor(0.5, 0.5, 0.5, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ eglMakeCurrent(egl.display(), esurface, esurface, egl.context());
}
void swap_buffers()
{
- eglSwapBuffers(gl.display(), esurface);
+ eglSwapBuffers(egl.display(), esurface);
}
static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
@@ -342,7 +414,7 @@ struct Surface
struct Framebuffer* lock_next()
{
bo_prev = bo_next;
- bo_next = gbm_surface_lock_front_buffer(gsurface);
+ bo_next = gsurface->lock_front_buffer();
FAIL_IF(!bo_next, "could not lock gbm buffer");
return drm_fb_get_from_bo(bo_next, card);
}
@@ -350,16 +422,20 @@ struct Surface
void free_prev()
{
if (bo_prev) {
- gbm_surface_release_buffer(gsurface, bo_prev);
+ gsurface->release_buffer(bo_prev);
bo_prev = 0;
}
}
+ uint32_t width() const { return m_width; }
+ uint32_t height() const { return m_height; }
+
+private:
Card& card;
GbmDevice& gdev;
- const GLState& gl;
+ const EglState& egl;
- GbmSurface gsurface;
+ unique_ptr<GbmSurface> gsurface;
EGLSurface esurface;
int m_width;
@@ -369,61 +445,22 @@ struct Surface
struct gbm_bo* bo_next;
};
-static void draw(uint32_t framenum, Surface& surface)
-{
- const GLState& gl = surface.gl;
-
- ESMatrix modelview;
-
- esMatrixLoadIdentity(&modelview);
- esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
- esRotate(&modelview, 45.0f + (0.75f * framenum), 1.0f, 0.0f, 0.0f);
- esRotate(&modelview, 45.0f - (0.5f * framenum), 0.0f, 1.0f, 0.0f);
- esRotate(&modelview, 10.0f + (0.45f * framenum), 0.0f, 0.0f, 1.0f);
-
- GLfloat aspect = (GLfloat)(surface.m_height) / (GLfloat)(surface.m_width);
-
- ESMatrix projection;
- esMatrixLoadIdentity(&projection);
- esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);
-
- ESMatrix modelviewprojection;
- esMatrixLoadIdentity(&modelviewprojection);
- esMatrixMultiply(&modelviewprojection, &modelview, &projection);
-
- float normal[9];
- normal[0] = modelview.m[0][0];
- normal[1] = modelview.m[0][1];
- normal[2] = modelview.m[0][2];
- normal[3] = modelview.m[1][0];
- normal[4] = modelview.m[1][1];
- normal[5] = modelview.m[1][2];
- normal[6] = modelview.m[2][0];
- normal[7] = modelview.m[2][1];
- normal[8] = modelview.m[2][2];
-
- glUniformMatrix4fv(gl.modelviewmatrix(), 1, GL_FALSE, &modelview.m[0][0]);
- glUniformMatrix4fv(gl.modelviewprojectionmatrix(), 1, GL_FALSE, &modelviewprojection.m[0][0]);
- glUniformMatrix3fv(gl.normalmatrix(), 1, GL_FALSE, normal);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
- glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
- glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
- glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
- glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
-}
-
class OutputHandler : private PageFlipHandlerBase
{
public:
- OutputHandler(Card& card, GbmDevice& gdev, const GLState& gl, Connector* connector, Crtc* crtc, Videomode& mode, Plane* plane, float rotation_mult)
+ OutputHandler(Card& card, GbmDevice& gdev, const EglState& egl, Connector* connector, Crtc* crtc, Videomode& mode, Plane* plane, float rotation_mult)
: m_frame_num(0), m_connector(connector), m_crtc(crtc), m_plane(plane), m_mode(mode),
m_rotation_mult(rotation_mult)
{
- m_surface = unique_ptr<Surface>(new Surface(card, gdev, gl, mode.hdisplay, mode.vdisplay));
- if (m_plane)
- m_surface2 = unique_ptr<Surface>(new Surface(card, gdev, gl, 400, 400));
+ m_surface1 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, mode.hdisplay, mode.vdisplay));
+ m_scene1 = unique_ptr<GlScene>(new GlScene());
+ m_scene1->set_viewport(m_surface1->width(), m_surface1->height());
+
+ if (m_plane) {
+ m_surface2 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, 400, 400));
+ m_scene2 = unique_ptr<GlScene>(new GlScene());
+ m_scene2->set_viewport(m_surface2->width(), m_surface2->height());
+ }
}
OutputHandler(const OutputHandler& other) = delete;
@@ -433,16 +470,14 @@ public:
{
int ret;
- m_surface->make_current();
- m_surface->clear();
- m_surface->swap_buffers();
- struct Framebuffer* fb = m_surface->lock_next();
+ m_surface1->make_current();
+ m_surface1->swap_buffers();
+ struct Framebuffer* fb = m_surface1->lock_next();
struct Framebuffer* planefb = 0;
if (m_plane) {
m_surface2->make_current();
- m_surface2->clear();
m_surface2->swap_buffers();
planefb = m_surface2->lock_next();
}
@@ -493,7 +528,7 @@ private:
s_flip_pending--;
- m_surface->free_prev();
+ m_surface1->free_prev();
if (m_plane)
m_surface2->free_prev();
@@ -505,18 +540,16 @@ private:
void queue_next()
{
- m_surface->make_current();
- m_surface->clear();
- draw(m_frame_num * m_rotation_mult, *m_surface);
- m_surface->swap_buffers();
- struct Framebuffer* fb = m_surface->lock_next();
+ m_surface1->make_current();
+ m_scene1->draw(m_frame_num * m_rotation_mult);
+ m_surface1->swap_buffers();
+ struct Framebuffer* fb = m_surface1->lock_next();
struct Framebuffer* planefb = 0;
if (m_plane) {
m_surface2->make_current();
- m_surface2->clear();
- draw(m_frame_num * m_rotation_mult * 2, *m_surface2);
+ m_scene2->draw(m_frame_num * m_rotation_mult * 2);
m_surface2->swap_buffers();
planefb = m_surface2->lock_next();
}
@@ -561,8 +594,11 @@ private:
Videomode m_mode;
Plane* m_root_plane;
- unique_ptr<Surface> m_surface;
- unique_ptr<Surface> m_surface2;
+ unique_ptr<GbmEglSurface> m_surface1;
+ unique_ptr<GbmEglSurface> m_surface2;
+
+ unique_ptr<GlScene> m_scene1;
+ unique_ptr<GlScene> m_scene2;
float m_rotation_mult;
};
@@ -577,7 +613,7 @@ int main(int argc, char *argv[])
Card card;
GbmDevice gdev(card);
- const GLState gl(gdev);
+ EglState egl(gdev.handle());
vector<unique_ptr<OutputHandler>> outputs;
vector<Plane*> used_planes;
@@ -605,7 +641,7 @@ int main(int argc, char *argv[])
if (plane)
used_planes.push_back(plane);
- auto out = new OutputHandler(card, gdev, gl, connector, crtc, mode, plane, rot_mult);
+ auto out = new OutputHandler(card, gdev, egl, connector, crtc, mode, plane, rot_mult);
outputs.emplace_back(out);
rot_mult *= 1.33;