#include "e_test_base.h"
+#include <png.h>
+#include <cairo.h>
+#include <pixman.h>
using ::testing::Test;
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+#endif
+
+#define UT_WAIT(fmt, ...) \
+ do \
+ { \
+ char ch; \
+ do \
+ { \
+ printf(fmt" [n]):next ", ##__VA_ARGS__); \
+ ch = tc_getchar(); \
+ } while (ch != 'n'); \
+ } while (0)
+
+char
+tc_getchar(void)
+{
+ int c = getchar();
+ int ch = c;
+
+ if (ch == '\n' || ch == '\r')
+ ch = 'y';
+ else if (ch < 'a')
+ ch += ('a' - 'A');
+
+ while (c != '\n' && c != EOF)
+ c = getchar();
+
+ return ch;
+}
+
etTCBase::etTCBase()
{
etRunner::get().flushEventQueue();
etRunner::get().setTCStart();
+ screenshot = efl_util_screenshot_initialize(CAPTURE_WIDTH, CAPTURE_HEIGHT);
+ if (screenshot == NULL)
+ ERR("efl_util_screenshot_initialize fail\n");
}
etTCBase::~etTCBase()
numGeomTw = 0;
numTw = 0;
+ if (screenshot)
+ {
+ efl_util_screenshot_deinitialize(screenshot);
+ screenshot = NULL;
+ }
+
etRunner::get().setTCEnd();
etRunner::get().flushEventQueue();
return EINA_TRUE;
}
+
+void
+_verifyTCGetBufferSize(tbm_surface_h buffer, int *buffer_w, int *buffer_h, int *stride)
+{
+ tbm_surface_info_s info;
+ int ret;
+
+ EINA_SAFETY_ON_NULL_RETURN(buffer);
+
+ ret = tbm_surface_get_info(buffer, &info);
+ if (ret != TBM_SURFACE_ERROR_NONE)
+ return;
+
+ if (buffer_w)
+ *buffer_w = info.planes[0].stride >> 2;
+
+ if (buffer_h)
+ *buffer_h = info.planes[0].size / info.planes[0].stride;
+
+ if (stride)
+ *stride = info.planes[0].stride;
+}
+
+static void
+_verifyTCdumpPng(const char *file, const void *data, int width, int height, int stride)
+{
+ pixman_image_t *image;
+ cairo_surface_t *cairo_surface;
+ cairo_status_t status;
+
+ image = pixman_image_create_bits_no_clear(PIXMAN_x8r8g8b8, width, height, (uint32_t *)data, stride);
+ if (image == (pixman_image_t *)NULL)
+ {
+ ERR("pixman_image_create_bits_no_clear failed");
+ return;
+ }
+
+ cairo_surface = cairo_image_surface_create_for_data((unsigned char *)pixman_image_get_data(image),
+ CAIRO_FORMAT_RGB24, pixman_image_get_width(image), pixman_image_get_height(image),
+ pixman_image_get_stride(image));
+ if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS)
+ {
+ ERR("cairo_image_surface_create_for_data failed");
+ pixman_image_unref(image);
+ return;
+ }
+
+ status = cairo_surface_write_to_png(cairo_surface, file);
+ if (status != CAIRO_STATUS_SUCCESS)
+ {
+ ERR("Failed to save image '%s': %s\n", file, cairo_status_to_string(status));
+ pixman_image_unref(image);
+ return;
+ }
+
+ cairo_surface_destroy(cairo_surface);
+ pixman_image_unref(image);
+}
+
+std::string
+_verifyTCMakeDumpPath(std::string basetype, std::string tcname)
+{
+ std::string path = "/tmp/etTestErr/";
+ std::string format = ".png";
+ int ret;
+
+ ret = mkdir(path.c_str(), 0755);
+ if (ret < 0 && errno != EEXIST)
+ {
+ ERR("mkdir failed. (%s)\n", path.c_str());
+ return "\0";
+ }
+
+ path = path + basetype + '/';
+ ret = mkdir(path.c_str(), 0755);
+ if (ret < 0 && errno != EEXIST)
+ {
+ ERR("mkdir failed. (%s)\n", path.c_str());
+ return "\0";
+ }
+
+ path = path + tcname + format;
+ ERR("path : %s", path.c_str());
+
+ return path;
+}
+
+void
+_verifyTCDumpBuffer(tbm_surface_h buffer, std::string basetype, std::string tcname)
+{
+ std::string dumppath;
+ tbm_surface_info_s info;
+ int ret;
+ int bo_cnt;
+ int bw, bh, stride;
+
+ EINA_SAFETY_ON_NULL_RETURN(buffer);
+
+ dumppath = _verifyTCMakeDumpPath(basetype, tcname);
+ if (dumppath.length() == 0)
+ {
+ ERR("getting dumppath failed");
+ return;
+ }
+
+ ret = tbm_surface_map(buffer, TBM_OPTION_READ, &info);
+ if (ret != TBM_SURFACE_ERROR_NONE)
+ {
+ ERR("tbm_surface_map failed");
+ return;
+ }
+
+ _verifyTCGetBufferSize(buffer, &bw, &bh, &stride);
+
+ bo_cnt = tbm_surface_internal_get_num_bos(buffer);
+ DBG("buffer: bo_cnt(%d) %dx%d(%dx%d) %c%c%c%c, plane: (%p+%d, %d,%d) (%p+%d, %d,%d) (%p+%d, %d,%d)",
+ bo_cnt, bw, bh, info.width, info.height, FOURCC_STR(info.format),
+ info.planes[0].ptr, info.planes[0].offset, info.planes[0].stride, info.planes[0].size,
+ info.planes[1].ptr, info.planes[1].offset, info.planes[1].stride, info.planes[1].size,
+ info.planes[2].ptr, info.planes[2].offset, info.planes[2].stride, info.planes[2].size);
+
+ if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
+ _verifyTCdumpPng(dumppath.c_str(), info.planes[0].ptr, bw, bh, stride);
+ else
+ DBG("not supported dump format");
+
+ tbm_surface_unmap(buffer);
+}
+
+std::string
+_verifyTCMakeRefPath(std::string basetype, std::string tcname)
+{
+ std::string path = "/usr/share/e_tizen_unittests/data/";
+ std::string format = ".png";
+
+ path = path + basetype + '/' + tcname + format;
+
+ return path;
+}
+
+pixman_format_code_t
+_verifyTCCairo2Pixman(cairo_format_t fmt)
+{
+ if (fmt == CAIRO_FORMAT_ARGB32)
+ return PIXMAN_a8r8g8b8;
+ else if (fmt == CAIRO_FORMAT_RGB24)
+ return PIXMAN_x8r8g8b8;
+ else
+ return (pixman_format_code_t)0;
+}
+
+static void
+destroy_cairo_surface(pixman_image_t *image, void *data)
+{
+ cairo_surface_t *surface = (cairo_surface_t *)data;
+
+ cairo_surface_destroy(surface);
+}
+
+pixman_image_t *
+_verifyTCConvertx8r8g8b8(pixman_image_t *image)
+{
+ pixman_image_t *ret;
+ int width;
+ int height;
+
+ if (pixman_image_get_format(image) == PIXMAN_x8r8g8b8)
+ return pixman_image_ref(image);
+
+ width = pixman_image_get_width(image);
+ height = pixman_image_get_height(image);
+
+ ret = pixman_image_create_bits_no_clear(PIXMAN_x8r8g8b8, width, height, NULL, 0);
+ if (ret == NULL)
+ {
+ ERR("pixman_image_create_bits_no_clear failed");
+ return NULL;
+ }
+
+ pixman_image_composite32(PIXMAN_OP_SRC, image, NULL, ret, 0, 0, 0, 0, 0, 0, width, height);
+
+ return ret;
+}
+
+pixman_image_t *
+_verifyTCLoadImage(const char *fname)
+{
+ pixman_image_t *image;
+ pixman_image_t *converted;
+ cairo_format_t cairo_fmt;
+ pixman_format_code_t pixman_fmt;
+ cairo_surface_t *reference_cairo_surface;
+ cairo_status_t status;
+ int width;
+ int height;
+ int stride;
+ void *data;
+
+ reference_cairo_surface = cairo_image_surface_create_from_png(fname);
+ cairo_surface_flush(reference_cairo_surface);
+ status = cairo_surface_status(reference_cairo_surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ {
+ ERR("Could not open %s: %s\n", fname, cairo_status_to_string(status));
+ cairo_surface_destroy(reference_cairo_surface);
+ return NULL;
+ }
+
+ cairo_fmt = cairo_image_surface_get_format(reference_cairo_surface);
+ pixman_fmt = _verifyTCCairo2Pixman(cairo_fmt);
+ ERR("pixman format(PIXMAN_a8r8g8b8:%d,PIXMAN_x8r8g8b8:%d) : %d", PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, pixman_fmt);
+ if (pixman_fmt == (pixman_format_code_t)0)
+ {
+ ERR("unknown format");
+ cairo_surface_destroy(reference_cairo_surface);
+ return NULL;
+ }
+
+ width = cairo_image_surface_get_width(reference_cairo_surface);
+ height = cairo_image_surface_get_height(reference_cairo_surface);
+ stride = cairo_image_surface_get_stride(reference_cairo_surface);
+ data = cairo_image_surface_get_data(reference_cairo_surface);
+
+ image = pixman_image_create_bits_no_clear(pixman_fmt, width, height, (uint32_t *)data, stride);
+ if (image == (pixman_image_t *)NULL)
+ {
+ ERR("pixman_image_create_bits_no_clear failed");
+ cairo_surface_destroy(reference_cairo_surface);
+ return NULL;
+ }
+
+ pixman_image_set_destroy_function(image, destroy_cairo_surface, reference_cairo_surface);
+
+ converted = _verifyTCConvertx8r8g8b8(image);
+ pixman_image_unref(image);
+
+ return converted;
+}
+
+Eina_Bool
+_verifyTCCheckPixel(uint32_t pix_a, uint32_t pix_b, int w, int h)
+{
+ int i, shift;
+ int diffmin = -3;
+ int diffmax = 4;
+ int val_a, val_b, diff;
+
+ for (shift = 8, i = 1; i < 4; shift += 8, i++)
+ {
+ val_a = (pix_a >> shift) & 0xFF;
+ val_b = (pix_b >> shift) & 0xFF;
+ diff = val_b - val_a;
+
+ if (diff < diffmin || diff > diffmax)
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+_verifyTCCheckImage(pixman_image_t *surface, pixman_image_t *ref)
+{
+ Eina_Bool ret = EINA_TRUE;
+ int surface_width, surface_height, surface_stride;
+ uint32_t *surface_data;
+ int pixman_width;
+ uint32_t *pixman_data;
+ int w, h;
+ uint32_t *current_surface_data;
+ uint32_t *current_pixman_data;
+
+ surface_width = pixman_image_get_width(surface);
+ surface_height = pixman_image_get_height(surface);
+ surface_stride = pixman_image_get_stride(surface);
+ surface_data = pixman_image_get_data(surface);
+
+ pixman_width = pixman_image_get_width(ref);
+ pixman_data = pixman_image_get_data(ref);
+
+ for (h = 0; h < surface_height; h++ )
+ {
+ current_surface_data = surface_data + h * surface_stride;
+ current_pixman_data = pixman_data + h * pixman_width;
+
+ for (w = 0; w < surface_width; w++)
+ {
+ ret = _verifyTCCheckPixel(*current_surface_data, *current_pixman_data, w, h);
+ if (ret == EINA_FALSE)
+ return ret;
+
+ current_surface_data++;
+ current_pixman_data++;
+ }
+ }
+
+ return ret;
+}
+
+Eina_Bool
+_verifyTC(tbm_surface_h surface, std::string basetype, std::string tcname)
+{
+ std::string refpath;
+ pixman_image_t *shot;
+ pixman_image_t *ref;
+ Eina_Bool ret = EINA_FALSE;
+ tbm_surface_info_s info;
+ int error;
+
+ refpath = _verifyTCMakeRefPath(basetype, tcname);
+ if (refpath.length() == 0)
+ {
+ ERR("getting dumppath failed");
+ return EINA_FALSE;
+ }
+
+ ref = _verifyTCLoadImage(refpath.c_str());
+ if (ref == (pixman_image_t *)NULL)
+ {
+ ERR("LoadImage failed");
+ return EINA_FALSE;
+ }
+
+ error = tbm_surface_map(surface, TBM_OPTION_READ, &info);
+ if (error != TBM_SURFACE_ERROR_NONE)
+ {
+ ERR("tbm_surface_map failed");
+ pixman_image_unref(ref);
+ return EINA_FALSE;
+ }
+
+ shot = pixman_image_create_bits_no_clear(PIXMAN_x8r8g8b8, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride >> 2);
+ if (shot == (pixman_image_t *)NULL)
+ {
+ ERR("pixman_image_create_bits_no_clear failed");
+ tbm_surface_unmap(surface);
+ pixman_image_unref(ref);
+ return EINA_FALSE;
+ }
+
+ ret = _verifyTCCheckImage(shot, ref);
+
+ pixman_image_unref(shot);
+ pixman_image_unref(ref);
+
+ return ret;
+}
+
+Eina_Bool
+etTCBase::verifyTC(std::string basetype, std::string tcname)
+{
+ tbm_surface_h surface = NULL;
+ Eina_Bool ret = EINA_FALSE;
+
+ surface = efl_util_screenshot_take_tbm_surface(screenshot);
+ if (surface == NULL)
+ {
+ ERR("screenshot failed");
+ return EINA_FALSE;
+ }
+
+ ret = _verifyTC(surface, basetype, tcname);
+ if (ret == EINA_FALSE)
+ {
+ ERR("verify failed");
+ _verifyTCDumpBuffer(surface, basetype, tcname);
+ }
+
+ tbm_surface_destroy(surface);
+// UT_WAIT("test");
+
+ return ret;
+}