Initial import
[glmemperf] / pixmapblittest.cpp
1 /**
2  * OpenGL ES 2.0 memory performance estimator
3  * Copyright (C) 2009 Nokia
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * \author Sami Kyöstilä <sami.kyostila@nokia.com>
20  *
21  * X11 pixmap surface test using shared memory and eglBindTexImage
22  */
23 #include "pixmapblittest.h"
24 #include "util.h"
25 #include "native.h"
26 #include <sstream>
27 #include <X11/Xlib.h>
28 #include <X11/Xutil.h>
29
30 template <typename TYPE>
31 void fillImage(XImage& img)
32 {
33     TYPE* d = reinterpret_cast<TYPE*>(img.data);
34
35     for (int y = 0; y < img.height; y++)
36     {
37         for (int x = 0; x < img.width; x++)
38         {
39             d[x] = x ^ y;
40         }
41         d += img.bytes_per_line / sizeof(TYPE);
42     }
43 }
44
45 PixmapBlitTest::PixmapBlitTest(int width, int height, EGLConfig config,
46                                bool rotate, float texW, float texH):
47     BlitTest(width, height, rotate, texW, texH),
48     m_config(config)
49 {
50     eglGetConfigAttrib(ctx.dpy, m_config, EGL_BUFFER_SIZE, &m_depth);
51 }
52
53 void PixmapBlitTest::prepare()
54 {
55     if (!isEGLExtensionSupported("EGL_NOKIA_texture_from_pixmap"))
56     {
57         fail("EGL_NOKIA_texture_from_pixmap not supported");
58     }
59
60     BlitTest::prepare();
61
62     EGLBoolean success;
63     initializeBlitter();
64
65     success = nativeCreatePixmap(ctx.nativeDisplay, ctx.dpy, m_config, m_width,
66                                  m_height, &m_pixmap);
67     assert(success);
68
69     success = fillPixmap();
70     assert(success);
71
72     const EGLint surfAttrs[] =
73     {
74         EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
75         EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
76         EGL_MIPMAP_TEXTURE, EGL_FALSE,
77         EGL_NONE
78     };
79
80     m_surface = eglCreatePixmapSurface(ctx.dpy, m_config, m_pixmap, surfAttrs);
81     assert(m_surface != EGL_NO_SURFACE);
82
83     success = eglBindTexImage(ctx.dpy, m_surface, EGL_BACK_BUFFER);
84     assert(success);
85
86     ASSERT_GL();
87 }
88
89 bool PixmapBlitTest::fillPixmap()
90 {
91     XImage* img = XGetImage(ctx.nativeDisplay, m_pixmap, 0, 0, m_width, m_height, ~0, ZPixmap);
92     if (!img)
93     {
94         return false;
95     }
96
97     assert(img->data);
98
99     switch (img->depth)
100     {
101     case 16:
102         fillImage<uint16_t>(*img);
103         break;
104     case 32:
105         fillImage<uint32_t>(*img);
106         break;
107     default:
108         assert(!"Unknown pixmap depth");
109         return false;
110     }
111
112     XGCValues gcValues;
113     GC gc = XCreateGC(ctx.nativeDisplay, m_pixmap, 0, &gcValues);
114     XPutImage(ctx.nativeDisplay, m_pixmap, gc, img, 0, 0, 0, 0, m_width, m_height);
115     XFreeGC(ctx.nativeDisplay, gc);
116     XDestroyImage(img);
117
118     return true;
119 }
120
121 void PixmapBlitTest::teardown()
122 {
123     eglReleaseTexImage(ctx.dpy, m_surface, EGL_BACK_BUFFER);
124     eglDestroySurface(ctx.dpy, m_surface);
125     nativeDestroyPixmap(ctx.nativeDisplay, m_pixmap);
126     BlitTest::teardown();
127 }
128
129 std::string PixmapBlitTest::name() const
130 {
131     std::stringstream s;
132
133     if (m_rotate)
134     {
135         s << "blit_pixmap_rot90_";
136     }
137     else
138     {
139         s << "blit_pixmap_";
140     }
141
142     switch (m_depth)
143     {
144     case 16:
145         s << "16bpp";
146         break;
147     case 32:
148         s << "32bpp";
149         break;
150     }
151
152     s << "_" << m_width << "x" << m_height;
153
154     return s.str();
155 }