Initial import
[glmemperf] / pixmapblittest.cpp
diff --git a/pixmapblittest.cpp b/pixmapblittest.cpp
new file mode 100644 (file)
index 0000000..8fb5759
--- /dev/null
@@ -0,0 +1,155 @@
+/**
+ * OpenGL ES 2.0 memory performance estimator
+ * Copyright (C) 2009 Nokia
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * \author Sami Kyöstilä <sami.kyostila@nokia.com>
+ *
+ * X11 pixmap surface test using shared memory and eglBindTexImage
+ */
+#include "pixmapblittest.h"
+#include "util.h"
+#include "native.h"
+#include <sstream>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+template <typename TYPE>
+void fillImage(XImage& img)
+{
+    TYPE* d = reinterpret_cast<TYPE*>(img.data);
+
+    for (int y = 0; y < img.height; y++)
+    {
+        for (int x = 0; x < img.width; x++)
+        {
+            d[x] = x ^ y;
+        }
+        d += img.bytes_per_line / sizeof(TYPE);
+    }
+}
+
+PixmapBlitTest::PixmapBlitTest(int width, int height, EGLConfig config,
+                               bool rotate, float texW, float texH):
+    BlitTest(width, height, rotate, texW, texH),
+    m_config(config)
+{
+    eglGetConfigAttrib(ctx.dpy, m_config, EGL_BUFFER_SIZE, &m_depth);
+}
+
+void PixmapBlitTest::prepare()
+{
+    if (!isEGLExtensionSupported("EGL_NOKIA_texture_from_pixmap"))
+    {
+        fail("EGL_NOKIA_texture_from_pixmap not supported");
+    }
+
+    BlitTest::prepare();
+
+    EGLBoolean success;
+    initializeBlitter();
+
+    success = nativeCreatePixmap(ctx.nativeDisplay, ctx.dpy, m_config, m_width,
+                                m_height, &m_pixmap);
+    assert(success);
+
+    success = fillPixmap();
+    assert(success);
+
+    const EGLint surfAttrs[] =
+    {
+        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
+        EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+        EGL_MIPMAP_TEXTURE, EGL_FALSE,
+        EGL_NONE
+    };
+
+    m_surface = eglCreatePixmapSurface(ctx.dpy, m_config, m_pixmap, surfAttrs);
+    assert(m_surface != EGL_NO_SURFACE);
+
+    success = eglBindTexImage(ctx.dpy, m_surface, EGL_BACK_BUFFER);
+    assert(success);
+
+    ASSERT_GL();
+}
+
+bool PixmapBlitTest::fillPixmap()
+{
+    XImage* img = XGetImage(ctx.nativeDisplay, m_pixmap, 0, 0, m_width, m_height, ~0, ZPixmap);
+    if (!img)
+    {
+        return false;
+    }
+
+    assert(img->data);
+
+    switch (img->depth)
+    {
+    case 16:
+        fillImage<uint16_t>(*img);
+        break;
+    case 32:
+        fillImage<uint32_t>(*img);
+        break;
+    default:
+        assert(!"Unknown pixmap depth");
+        return false;
+    }
+
+    XGCValues gcValues;
+    GC gc = XCreateGC(ctx.nativeDisplay, m_pixmap, 0, &gcValues);
+    XPutImage(ctx.nativeDisplay, m_pixmap, gc, img, 0, 0, 0, 0, m_width, m_height);
+    XFreeGC(ctx.nativeDisplay, gc);
+    XDestroyImage(img);
+
+    return true;
+}
+
+void PixmapBlitTest::teardown()
+{
+    eglReleaseTexImage(ctx.dpy, m_surface, EGL_BACK_BUFFER);
+    eglDestroySurface(ctx.dpy, m_surface);
+    nativeDestroyPixmap(ctx.nativeDisplay, m_pixmap);
+    BlitTest::teardown();
+}
+
+std::string PixmapBlitTest::name() const
+{
+    std::stringstream s;
+
+    if (m_rotate)
+    {
+        s << "blit_pixmap_rot90_";
+    }
+    else
+    {
+        s << "blit_pixmap_";
+    }
+
+    switch (m_depth)
+    {
+    case 16:
+        s << "16bpp";
+        break;
+    case 32:
+        s << "32bpp";
+        break;
+    }
+
+    s << "_" << m_width << "x" << m_height;
+
+    return s.str();
+}