/* Bilinear filtering from Wikipedia */ uint32_t getBilinearFilteredPixelColor(sprite_t * tex, double u, double v) { u *= tex->width; v *= tex->height; int x = floor(u); int y = floor(v); if (x >= tex->width) return 0; if (y >= tex->height) return 0; double u_ratio = u - x; double v_ratio = v - y; double u_o = 1 - u_ratio; double v_o = 1 - v_ratio; double r_ALP = 255; if (tex->alpha == ALPHA_MASK) { if (x == tex->width - 1 || y == tex->height - 1) return (SPRITE(tex,x,y) | 0xFF000000) & (0xFFFFFF + _RED(SMASKS(tex,x,y)) * 0x1000000); r_ALP = (_RED(SMASKS(tex,x,y)) * u_o + _RED(SMASKS(tex,x+1,y)) * u_ratio) * v_o + (_RED(SMASKS(tex,x,y+1)) * u_o + _RED(SMASKS(tex,x+1,y+1)) * u_ratio) * v_ratio; } else if (tex->alpha == ALPHA_EMBEDDED) { if (x == tex->width - 1 || y == tex->height - 1) return (SPRITE(tex,x,y) | 0xFF000000) & (0xFFFFFF + _ALP(SPRITE(tex,x,y)) * 0x1000000); r_ALP = (_ALP(SPRITE(tex,x,y)) * u_o + _ALP(SPRITE(tex,x+1,y)) * u_ratio) * v_o + (_ALP(SPRITE(tex,x,y+1)) * u_o + _ALP(SPRITE(tex,x+1,y+1)) * u_ratio) * v_ratio; } if (x == tex->width - 1 || y == tex->height - 1) return SPRITE(tex,x,y); double r_RED = (_RED(SPRITE(tex,x,y)) * u_o + _RED(SPRITE(tex,x+1,y)) * u_ratio) * v_o + (_RED(SPRITE(tex,x,y+1)) * u_o + _RED(SPRITE(tex,x+1,y+1)) * u_ratio) * v_ratio; double r_BLU = (_BLU(SPRITE(tex,x,y)) * u_o + _BLU(SPRITE(tex,x+1,y)) * u_ratio) * v_o + (_BLU(SPRITE(tex,x,y+1)) * u_o + _BLU(SPRITE(tex,x+1,y+1)) * u_ratio) * v_ratio; double r_GRE = (_GRE(SPRITE(tex,x,y)) * u_o + _GRE(SPRITE(tex,x+1,y)) * u_ratio) * v_o + (_GRE(SPRITE(tex,x,y+1)) * u_o + _GRE(SPRITE(tex,x+1,y+1)) * u_ratio) * v_ratio; return rgb(r_RED,r_GRE,r_BLU) & (0xFFFFFF + (int)r_ALP * 0x1000000); }
uint32_t alpha_blend(uint32_t bottom, uint32_t top, uint32_t mask) { uint8_t a = _RED(mask); uint8_t red = (_RED(bottom) * (255 - a) + _RED(top) * a) / 255; uint8_t gre = (_GRE(bottom) * (255 - a) + _GRE(top) * a) / 255; uint8_t blu = (_BLU(bottom) * (255 - a) + _BLU(top) * a) / 255; uint8_t alp = (int)a + (int)_ALP(bottom) > 255 ? 255 : a + _ALP(bottom); return rgba(red,gre,blu, alp); }
static void _box_blur_vertical(gfx_context_t * _src, int radius) { uint32_t * p = (uint32_t *)_src->backbuffer; int w = _src->width; int h = _src->height; int half_radius = radius / 2; uint32_t * out_color = calloc(sizeof(uint32_t), h); int old_offset = -(half_radius + 1) * w; int new_offset = (half_radius) * w; for (int x = 0; x < w; x++) { int hits = 0; int r = 0; int g = 0; int b = 0; int a = 0; int index = -half_radius * w + x; for (int y = -half_radius; y < h; y++) { int old_p = y - half_radius - 1; if (old_p >= 0) { uint32_t col = p[clamp(index + old_offset, 0, w*h-1)]; if (col != 0) { r -= _RED(col); g -= _GRE(col); b -= _BLU(col); a -= _ALP(col); } hits--; } int newPixel = y + half_radius; if (newPixel < h) { uint32_t col = p[clamp(index + new_offset, 0, w*h-1)]; if (col != 0) { r += _RED(col); g += _GRE(col); b += _BLU(col); a += _ALP(col); } hits++; } if (y >= 0) { out_color[y] = rgba(r / hits, g / hits, b / hits, a / hits); } index += w; } for (int y = 0; y < h; y++) { p[y * w + x] = out_color[y]; } } free(out_color); }
uint32_t BlendPixels(uint32_t bottom, uint32_t top) { uint8_t a = _ALP(top); uint8_t b = (uint8_t)(((uint32_t)_ALP(bottom) * (255 - a)) / 255); uint8_t alp = a + b; uint8_t red = alp ? (uint8_t)(uint32_t)((_RED(bottom) * b + _RED(top) * a) / alp) : 0; uint8_t gre = alp ? (uint8_t)(uint32_t)((_GRE(bottom) * b + _GRE(top) * a) / alp) : 0; uint8_t blu = alp ? (uint8_t)(uint32_t)((_BLU(bottom) * b + _BLU(top) * a) / alp) : 0; return GetRGBA(red, gre, blu, alp); }
static void _box_blur_horizontal(gfx_context_t * _src, int radius) { uint32_t * p = (uint32_t *)_src->backbuffer; int w = _src->width; int h = _src->height; int half_radius = radius / 2; int index = 0; uint32_t * out_color = calloc(sizeof(uint32_t), w); for (int y = 0; y < h; y++) { int hits = 0; int r = 0; int g = 0; int b = 0; int a = 0; for (int x = -half_radius; x < w; x++) { int old_p = x - half_radius - 1; if (old_p >= 0) { uint32_t col = p[clamp(index + old_p, 0, w*h-1)]; if (col) { r -= _RED(col); g -= _GRE(col); b -= _BLU(col); a -= _ALP(col); } hits--; } int newPixel = x + half_radius; if (newPixel < w) { int col = p[clamp(index + newPixel, 0, w*h-1)]; if (col != 0) { r += _RED(col); g += _GRE(col); b += _BLU(col); a += _ALP(col); } hits++; } if (x >= 0) { out_color[x] = rgba(r / hits, g / hits, b / hits, a / hits); } } for (int x = 0; x < w; x++) { p[index + x] = out_color[x]; } index += w; } free(out_color); }
static void inplace_reorder(char * samples, int size) { for (int i = 0; i < size; ++i) { uint32_t c = ((uint32_t *)samples)[i]; char b = _RED(c); char g = _GRE(c); char r = _BLU(c); char a = _ALP(c); ((uint32_t *)samples)[i] = rgba(r,g,b,a); } }
uint32_t premultiply(uint32_t color) { uint16_t a = _ALP(color); uint16_t r = _RED(color); uint16_t g = _GRE(color); uint16_t b = _BLU(color); r = r * a / 255; g = g * a / 255; b = b * a / 255; return rgba(r,g,b,a); }
/* perfexpert_util_file_exists */ int perfexpert_util_file_exists(const char *file) { if (NULL == file) { OUTPUT(("%s", _ERROR((char *)"file is NULL"))); return PERFEXPERT_ERROR; } if (0 != access(file, F_OK)) { OUTPUT_VERBOSE((10, "%s (%s)", _RED((char *)"file not found"), file)); return PERFEXPERT_ERROR; } return PERFEXPERT_SUCCESS; }
/* perfexpert_util_dir_exists */ int perfexpert_util_dir_exists(const char *dir) { struct stat sb; if (NULL == dir) { OUTPUT(("%s", _ERROR((char *)"dir is NULL"))); return PERFEXPERT_ERROR; } if (0 != stat(dir, &sb)) { OUTPUT_VERBOSE((1, "%s (%s)", _RED((char *)"directory not found or you do not have permissions"), dir)); return PERFEXPERT_ERROR; } if (!S_ISDIR(sb.st_mode)) { OUTPUT_VERBOSE((1, "%s (%s)", _RED((char *)"is not a directory"), dir)); return PERFEXPERT_ERROR; } return PERFEXPERT_SUCCESS; }
/* * Draw a character to a context. */ static void draw_char(FT_Bitmap * bitmap, int x, int y, uint32_t fg, gfx_context_t * ctx) { int i, j, p, q; int x_max = x + bitmap->width; int y_max = y + bitmap->rows; for (j = y, q = 0; j < y_max; j++, q++) { for ( i = x, p = 0; i < x_max; i++, p++) { uint32_t a = _ALP(fg); a = (a * bitmap->buffer[q * bitmap->width + p]) / 255; uint32_t tmp = premultiply(rgba(_RED(fg),_GRE(fg),_BLU(fg),a)); SGFX(ctx->backbuffer,i,j,ctx->width) = alpha_blend_rgba(SGFX(ctx->backbuffer,i,j,ctx->width),tmp); } } }
/* perfexpert_util_file_is_writable */ int perfexpert_util_file_is_writable(const char *file) { if (NULL == file) { OUTPUT(("%s", _ERROR((char *)"filename not specified"))); return PERFEXPERT_ERROR; } if (0 != access(file, W_OK)) { OUTPUT_VERBOSE((10, "%s (%s)", _RED((char *)"file is not writable or does not exist"), file)); return PERFEXPERT_ERROR; } return PERFEXPERT_SUCCESS; }
void context_to_png(FILE * file, gfx_context_t * ctx) { png_structp png_ptr = NULL; png_infop info_ptr = NULL; int32_t x, y; png_byte ** row_pointers = NULL; int status = -1; int depth = 8; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); if (setjmp(png_jmpbuf(png_ptr))) { goto png_write_failure; } png_set_IHDR(png_ptr, info_ptr, ctx->width, ctx->height, depth, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); row_pointers = png_malloc(png_ptr, ctx->height * sizeof(png_byte *)); for (y = 0; y < ctx->height; ++y) { png_byte * row = png_malloc(png_ptr, sizeof(uint8_t) * ctx->width * sizeof(uint32_t)); row_pointers[y] = row; for (x = 0; x < ctx->width; ++x) { uint32_t pixel = GFX(ctx, x, y); *row++ = _RED(pixel); *row++ = _GRE(pixel); *row++ = _BLU(pixel); *row++ = _ALP(pixel); } } png_init_io(png_ptr, file); png_set_rows(png_ptr, info_ptr, row_pointers); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); for (y = 0; y < ctx->height; y++) { png_free(png_ptr, row_pointers[y]); } png_free(png_ptr, row_pointers); fprintf(stderr, "Done writing PNG.\n"); return; png_write_failure: fprintf(stderr, "There was an exception while trying to write out a PNG file :(\n"); return; }
uint32_t alpha_blend_rgba(uint32_t bottom, uint32_t top) { if (_ALP(bottom) == 0) return top; if (_ALP(top) == 255) return top; if (_ALP(top) == 0) return bottom; #if DONT_USE_FLOAT_FOR_ALPHA uint16_t a = _ALP(top); uint16_t c = 255 - a; uint16_t b = ((int)_ALP(bottom) * c) / 255; uint16_t alp = min16(a + b, 255); uint16_t red = min16((uint32_t)(_RED(bottom) * c + _RED(top) * 255) / 255, 255); uint16_t gre = min16((uint32_t)(_GRE(bottom) * c + _GRE(top) * 255) / 255, 255); uint16_t blu = min16((uint32_t)(_BLU(bottom) * c + _BLU(top) * 255) / 255, 255); return rgba(red,gre,blu,alp); #else double a = _ALP(top) / 255.0; double c = 1.0 - a; double b = (_ALP(bottom) / 255.0) * c; double alp = a + b; if (alp > 1.0) alp = 1.0; double red = (_RED(bottom) / 255.0) * c + (_RED(top) / 255.0); if (red > 1.0) red = 1.0; double gre = (_GRE(bottom) / 255.0) * c + (_GRE(top) / 255.0); if (gre > 1.0) gre = 1.0; double blu = (_BLU(bottom) / 255.0) * c + (_BLU(top) / 255.0); if (blu > 1.0) blu = 1.0; return rgba(red * 255, gre * 255, blu * 255, alp * 255); #endif }
// This function takes the output of running VTune and creates a report CSV file // The results of running VTune are in results_folder // The output of this function is in parse_file // The command it executes is like: // amplxe-cl -R hw-events -r results_folder -group-by=function -format=csv -report-output=parse_file -csv-delimiter=',' // amplxe-cl -report hw-events -group-by=function -group-by=module -group-by=source-file -group-by=source-line -group-by=thread -r results_folder -format=csv -report-output=parse-file -csv-delimiter=',' int create_report(char* results_folder, const char* parse_file) { struct timespec time_start, time_end, time_diff; char *argv[MAX_ARGUMENTS_COUNT]; int argc = 0, i, rc; char buffer[MAX_BUFFER_SIZE]; test_t test; argv[argc] = VTUNE_CL_BIN; argc++; argv[argc] = VTUNE_ACT_REPORT; argc++; argv[argc] = VTUNE_RPT_HW; argc++; argv[argc] = "-group-by=function"; argc++; argv[argc] = "-group-by=module"; argc++; argv[argc] = "-group-by=source-file"; argc++; argv[argc] = "-group-by=source-line"; argc++; if (globals.output_mode == HYBRID_OUTPUT) { argv[argc] = "-group-by=thread"; argc++; } argv[argc] = "-r"; argc++; argv[argc] = my_module_globals.res_folder; argc++; argv[argc] = "-format=csv"; argc++; strcpy(buffer, "-report-output="); strcat(buffer, parse_file); argv[argc] = buffer; argc++; argv[argc] = "-csv-delimiter=','"; argc++; argv[argc] = NULL; /* Not using OUTPUT_VERBOSEbecause I want only one line */ if (8 <= globals.verbose) { printf("%s %s", PROGRAM_PREFIX, _YELLOW("command line:")); for (i = 0; i < argc; i++) { printf(" %s", argv[i]); } printf("\n"); } /* The super-ninja test sctructure */ PERFEXPERT_ALLOC(char, test.output, (strlen(globals.moduledir) + 14)); sprintf(test.output, "%s/vtune.output", globals.moduledir); test.input = my_module_globals.inputfile; test.info = globals.program; clock_gettime(CLOCK_MONOTONIC, &time_start); /* fork_and_wait_and_pray */ rc = perfexpert_fork_and_wait(&test, (char **)argv); /* Evaluate results if required to */ if (PERFEXPERT_FALSE == my_module_globals.ignore_return_code) { switch (rc) { case PERFEXPERT_FAILURE: case PERFEXPERT_ERROR: OUTPUT(("%s (return code: %d) Usually, this means that an error" " happened during the program execution. To see the program" "'s output, check the content of this file: [%s]. If you " "want to PerfExpert ignore the return code next time you " "run this program, set the 'return-code' option for the " "Vtune module. See 'perfexpert -H vtune' for details.", _ERROR("the target program returned non-zero"), rc, test.output)); return PERFEXPERT_ERROR; case PERFEXPERT_SUCCESS: OUTPUT_VERBOSE((7, "[ %s ]", _BOLDGREEN("OK"))); break; default: break; } } /* Calculate and display runtime */ clock_gettime(CLOCK_MONOTONIC, &time_end); perfexpert_time_diff(&time_diff, &time_start, &time_end); OUTPUT((" [1/1] %lld.%.9ld seconds (includes measurement overhead)", (long long)time_diff.tv_sec, time_diff.tv_nsec)); PERFEXPERT_DEALLOC(test.output); /* Run the AFTER program */ if (NULL != my_module_globals.after[0]) { PERFEXPERT_ALLOC(char, test.output, (strlen(globals.moduledir) + 20)); sprintf(test.output, "%s/after.output", globals.moduledir); test.input = NULL; test.info = my_module_globals.after[0]; if (0 != perfexpert_fork_and_wait(&test, (char **)my_module_globals.after)) { OUTPUT(("%s", _RED("'after' command return non-zero"))); } PERFEXPERT_DEALLOC(test.output); }