From 05cab1424b32cdbdc3980fe0e5062ad9b7ec4b66 Mon Sep 17 00:00:00 2001 From: Aloz1 Date: Thu, 28 Jul 2016 09:39:16 +1000 Subject: [PATCH 1/6] Improved pixel drawing for bitmaps Added an SDL_Surface as a cache for the bitmap so that pixels can be transfered all at once to the GPU --- Backend/SGSDL2/src/SGSDL2Graphics.cpp | 323 +++++++++++++++++++------- Backend/SGSDL2/src/SGSDL2Graphics.h | 18 +- Backend/Test/src/main.cpp | 115 +++++++-- 3 files changed, 350 insertions(+), 106 deletions(-) diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.cpp b/Backend/SGSDL2/src/SGSDL2Graphics.cpp index ff7b62d0..379d62e2 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.cpp +++ b/Backend/SGSDL2/src/SGSDL2Graphics.cpp @@ -616,6 +616,110 @@ void _sgsdl2_destroy_bitmap(sg_bitmap_be *bitmap_be) free(bitmap_be); } +// +// Pixel Functions +// + +Uint32 _get_pixel(SDL_Surface *surface, int x, int y) +{ + Uint8 *p; + + if(!surface->pixels) return 0; + + p = static_cast(surface->pixels) + + y * surface->pitch + + x * surface->format->BytesPerPixel; + + if(x < 0 || y < 0 || x >= surface->w || y >= surface->h) return 0; + + uint32_t color; + + switch(surface->format->BytesPerPixel) { + case 1: + color = *p; + break; + case 2: + color = *reinterpret_cast(p); + break; + case 3: +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + color = static_cast(p[0] << 16 | p[1] << 8 | p[2]); +#else + color = static_cast(p[0] | p[1] << 8 | p[2] << 16); +#endif + break; + case 4: + color = *reinterpret_cast(p); + break; + default: + color = 0; + } + + uint8_t r, g, b, a; + + SDL_GetRGBA(color, surface->format, &r, &g, &b, &a); + return (uint32_t)(r << 24 | g << 16 | b << 8 | a); + +// switch(surface->format->BytesPerPixel) { +// case 1: +// return *p; +// case 2: +// return *(Uint16 *)p; +// case 3: +//#if SDL_BYTEORDER == SDL_BIG_ENDIAN +// return static_cast(p[0] << 16 | p[1] << 8 | p[2]); +//#else +// return static_cast(p[0] | p[1] << 8 | p[2] << 16); +//#endif +// case 4: +// uint32_t color; +// uint8_t r, g, b, a; +// color = *(Uint32 *)p; +// +// r = (uint8_t)((color & surface->format->Rmask) >> (surface->format->Rshift)); +// g = (uint8_t)((color & surface->format->Gmask) >> (surface->format->Gshift)); +// b = (uint8_t)((color & surface->format->Bmask) >> (surface->format->Bshift)); +// a = (uint8_t)((color & surface->format->Amask) >> (surface->format->Ashift)); +// return (uint32_t)(r << 24 | g << 16 | b << 8 | a); +// default: +// return 0; +// } +} + +void _set_pixel(SDL_Surface *surface, sg_color clr, int x, int y) +{ + Uint8 *p; + + if(!surface->pixels) return; + + p = static_cast(surface->pixels) + + y * surface->pitch + + x * surface->format->BytesPerPixel; + + if(x < 0 || y < 0 || x >= surface->w || y >= surface->h) return; + + Uint32 pixel = SDL_MapRGBA( + surface->format, + static_cast(clr.r * 255), + static_cast(clr.g * 255), + static_cast(clr.b * 255), + static_cast(clr.a * 255) + ); + + // Convert Uint32 into 4 bytes (now in the correct order, as dictated by SDL_MapRGBA) +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + p[0] = static_cast(pixel>>24); + p[1] = static_cast(pixel>>16); + p[2] = static_cast(pixel>>8); + p[3] = static_cast(pixel); +#else + p[0] = static_cast(pixel); + p[1] = static_cast(pixel>>8); + p[2] = static_cast(pixel>>16); + p[3] = static_cast(pixel>>24); +#endif +} + //-------------------------------------------------------------------------------------- // @@ -623,6 +727,7 @@ void _sgsdl2_destroy_bitmap(sg_bitmap_be *bitmap_be) // //-------------------------------------------------------------------------------------- + bool _sgsdl2_open_window(const char *title, int width, int height, unsigned int options, sg_window_be *window_be) { if( _sgsdl2_has_initial_window ) @@ -774,6 +879,21 @@ void _sgsdl2_clear_window(sg_drawing_surface *window, sg_color clr) } } +void _sgsdl2_clear_sdl_surface(SDL_Surface *surface, sg_color clr) +{ + if ( surface ) + { + for(int y = 0; y < surface->h; y++) + { + for(int x = 0; x < surface->w; x++) + { + _set_pixel(surface, clr, x, y); + } + } + } +} + + void _sgsdl2_clear_bitmap(sg_drawing_surface *bitmap, sg_color clr) { sg_bitmap_be * bitmap_be = static_cast(bitmap->_data); @@ -793,6 +913,62 @@ void _sgsdl2_clear_bitmap(sg_drawing_surface *bitmap, sg_color clr) _sgsdl2_restore_default_render_target(window, bitmap_be); } + + _sgsdl2_clear_sdl_surface(bitmap_be->surface, clr); + } +} + +void _sgsdl2_texture_to_surface(sg_drawing_surface *surface) +{ + if( surface && surface->kind == SGDS_Bitmap ) + { + sg_bitmap_be *bitmap_be= static_cast(surface->_data); + + if( bitmap_be->last_draw_loc != SG_BITMAP_TEXTURE ) return; + + SDL_Rect rect = {0, 0, surface->width, surface->height}; + _sgsdl2_set_renderer_target(0, bitmap_be); + + SDL_RenderReadPixels( + _sgsdl2_open_windows[0]->renderer, + &rect, + SDL_PIXELFORMAT_RGBA8888, + bitmap_be->surface->pixels, + surface->width * 4 + ); + + bitmap_be->last_draw_loc = SG_BITMAP_NONE; + } +} + +void _sgsdl2_surface_to_texture(sg_drawing_surface *surface) +{ + if( surface && surface->kind == SGDS_Bitmap ) + { + sg_bitmap_be *bitmap_be = static_cast(surface->_data); + + if( bitmap_be->last_draw_loc != SG_BITMAP_SURFACE ) return; + + Uint32 count = _sgsdl2_renderer_count( surface ); + for( Uint32 i = 0; i < count; i++ ) + { + /* + SDL_UpdateTexture( + bitmap_be->texture[i], + NULL, + bitmap_be->surface->pixels, + bitmap_be->surface->pitch + ); + */ + SDL_UpdateTexture( + bitmap_be->texture[i], + NULL, + bitmap_be->surface->pixels, + bitmap_be->surface->pitch + ); + } + + bitmap_be->last_draw_loc = SG_BITMAP_NONE; } } @@ -911,6 +1087,9 @@ void sgsdl2_draw_aabb_rect(sg_drawing_surface *surface, sg_color clr, float *dat static_cast(data[3]) }; + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) @@ -939,6 +1118,9 @@ void sgsdl2_fill_aabb_rect(sg_drawing_surface *surface, sg_color clr, float *dat static_cast(data[3]) }; + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) @@ -975,6 +1157,9 @@ void sgsdl2_draw_rect(sg_drawing_surface *surface, sg_color clr, float *data, in int x2 = static_cast(data[2]), y2 = static_cast(data[3]); int x3 = static_cast(data[4]), y3 = static_cast(data[5]); int x4 = static_cast(data[6]), y4 = static_cast(data[7]); + + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); @@ -1021,6 +1206,9 @@ void sgsdl2_fill_rect(sg_drawing_surface *surface, sg_color clr, float *data, in y[1] = static_cast(data[3]); y[2] = static_cast(data[7]); // Swap last 2 for SDL_gfx order y[3] = static_cast(data[5]); + + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); @@ -1060,6 +1248,9 @@ void sgsdl2_draw_triangle(sg_drawing_surface *surface, sg_color clr, float *data int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int x2 = static_cast(data[2]), y2 = static_cast(data[3]); int x3 = static_cast(data[4]), y3 = static_cast(data[5]); + + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); @@ -1089,6 +1280,8 @@ void sgsdl2_fill_triangle(sg_drawing_surface *surface, sg_color clr, float *data float x2 = data[2], y2 = data[3]; float x3 = data[4], y3 = data[5]; + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); @@ -1126,6 +1319,9 @@ void sgsdl2_draw_ellipse(sg_drawing_surface *surface, sg_color clr, float *data, // 4 values = 1 point w + h int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int w = static_cast(data[2]), h = static_cast(data[3]); + + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); @@ -1158,6 +1354,9 @@ void sgsdl2_fill_ellipse(sg_drawing_surface *surface, sg_color clr, float *data, // 4 values = 1 point w + h int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int w = static_cast(data[2]), h = static_cast(data[3]); + + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); @@ -1195,6 +1394,18 @@ void sgsdl2_draw_pixel(sg_drawing_surface *surface, sg_color clr, float *data, i // 2 values = 1 point int x1 = static_cast(data[0]), y1 = static_cast(data[1]); + if (surface->kind == SGDS_Bitmap) + { + sg_bitmap_be *bitmap_be = static_cast(surface->_data); + + _sgsdl2_texture_to_surface(surface); + + _set_pixel(bitmap_be->surface, clr, x1, y1); + bitmap_be->last_draw_loc = SG_BITMAP_SURFACE; + + return; + } + unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) @@ -1265,6 +1476,9 @@ void sgsdl2_draw_circle(sg_drawing_surface *surface, sg_color clr, float *data, int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int r = static_cast(data[2]); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) @@ -1345,8 +1559,11 @@ void sgsdl2_draw_line(sg_drawing_surface *surface, sg_color clr, float *data, in if ( w == 0 ) return; - unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + unsigned int count = _sgsdl2_renderer_count(surface); + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1470,81 +1687,16 @@ void sgsdl2_clear_clip_rect(sg_drawing_surface *surface) } } -Uint32 _get_pixel(SDL_Surface *surface, int x, int y) -{ - Uint8 *p; - - if(!surface->pixels) return 0; - - p = static_cast(surface->pixels) - + y * surface->pitch - + x * surface->format->BytesPerPixel; - - if(x < 0 || y < 0 || x >= surface->w || y >= surface->h) return 0; - - uint32_t color; - - switch(surface->format->BytesPerPixel) { - case 1: - color = *p; - break; - case 2: - color = *reinterpret_cast(p); - break; - case 3: -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - color = static_cast(p[0] << 16 | p[1] << 8 | p[2]); -#else - color = static_cast(p[0] | p[1] << 8 | p[2] << 16); -#endif - break; - case 4: - color = *reinterpret_cast(p); - break; - default: - color = 0; - } - - uint8_t r, g, b, a; - - SDL_GetRGBA(color, surface->format, &r, &g, &b, &a); - return (uint32_t)(r << 24 | g << 16 | b << 8 | a); - -// switch(surface->format->BytesPerPixel) { -// case 1: -// return *p; -// case 2: -// return *(Uint16 *)p; -// case 3: -//#if SDL_BYTEORDER == SDL_BIG_ENDIAN -// return static_cast(p[0] << 16 | p[1] << 8 | p[2]); -//#else -// return static_cast(p[0] | p[1] << 8 | p[2] << 16); -//#endif -// case 4: -// uint32_t color; -// uint8_t r, g, b, a; -// color = *(Uint32 *)p; -// -// r = (uint8_t)((color & surface->format->Rmask) >> (surface->format->Rshift)); -// g = (uint8_t)((color & surface->format->Gmask) >> (surface->format->Gshift)); -// b = (uint8_t)((color & surface->format->Bmask) >> (surface->format->Bshift)); -// a = (uint8_t)((color & surface->format->Amask) >> (surface->format->Ashift)); -// return (uint32_t)(r << 24 | g << 16 | b << 8 | a); -// default: -// return 0; -// } -} // // To Pixels // - -void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz); void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz) { if ( ! surface || ! surface->_data || surface->width * surface->height != sz) return; + SDL_Rect rect = {0, 0, surface->width, surface->height}; + switch (surface->kind) { case SGDS_Window: @@ -1561,20 +1713,14 @@ void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz) case SGDS_Bitmap: { sg_bitmap_be * bitmap_be = static_cast(surface->_data); + + _sgsdl2_texture_to_surface(surface); - if ( ! bitmap_be->surface ) // read from texture - { - _sgsdl2_bitmap_be_texture_to_pixels(bitmap_be, pixels, sz, surface->width, surface->height); - } - else + for (int y = 0; y < surface->height; y++) { - // read from surface - for (int y = 0; y < surface->height; y++) + for(int x = 0; x < surface->width; x++) { - for(int x = 0; x < surface->width; x++) - { - pixels[y * surface->width + x] = static_cast(_get_pixel(bitmap_be->surface, x, y)); - } + pixels[y * surface->width + x] = static_cast(_get_pixel(bitmap_be->surface, x, y)); } } break; @@ -1607,8 +1753,6 @@ void sgsdl2_show_border(sg_drawing_surface *surface, int border) } case SGDS_Bitmap: - break; - case SGDS_Unknown: break; } @@ -1631,8 +1775,6 @@ void sgsdl2_show_fullscreen(sg_drawing_surface *surface, int fullscreen) } case SGDS_Bitmap: - break; - case SGDS_Unknown: break; } @@ -1690,8 +1832,6 @@ void sgsdl2_resize(sg_drawing_surface *surface, int width, int height) } case SGDS_Bitmap: - break; - case SGDS_Unknown: break; } @@ -1830,6 +1970,7 @@ sg_drawing_surface sgsdl2_create_bitmap(int width, int height) sg_drawing_surface result = { SGDS_Unknown, 0, 0, NULL }; result.kind = SGDS_Bitmap; + sg_bitmap_be *data = static_cast(malloc(sizeof(sg_bitmap_be))); result._data = data; @@ -1838,6 +1979,7 @@ sg_drawing_surface sgsdl2_create_bitmap(int width, int height) data->clipped = false; data->clip = {0, 0, width, height}; + data->last_draw_loc = SG_BITMAP_NONE; data->drawable = true; data->surface = NULL; data->texture = static_cast(malloc(sizeof(SDL_Texture*) * _sgsdl2_num_open_windows)); @@ -1849,11 +1991,15 @@ sg_drawing_surface sgsdl2_create_bitmap(int width, int height) SDL_SetTextureBlendMode(data->texture[i], SDL_BLENDMODE_BLEND); _sgsdl2_set_renderer_target(i, data); - SDL_SetRenderDrawColor(_sgsdl2_open_windows[i]->renderer, 255, 255, 255, 0); + SDL_SetRenderDrawColor(_sgsdl2_open_windows[i]->renderer, 0xff, 0xff, 0xff, 0); SDL_RenderClear(_sgsdl2_open_windows[i]->renderer); _sgsdl2_restore_default_render_target(i, data); } + //data->surface = SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0xff0000, 0xff00, 0xff); + data->surface = SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0xff0000, 0xff00, 0xff); + _sgsdl2_clear_sdl_surface(data->surface,{0xff, 0xff, 0xff, 0xff}); + _sgsdl2_add_bitmap(data); return result; } @@ -1863,14 +2009,14 @@ sg_drawing_surface sgsdl2_load_bitmap(const char * filename) internal_sgsdl2_init(); sg_drawing_surface result = { SGDS_Unknown, 0, 0, NULL }; - SDL_Surface *surface; - surface = IMG_Load(filename); + SDL_Surface *surface = IMG_Load(filename); if ( ! surface ) { std::cout << "error loading image " << IMG_GetError() << std::endl; return result; } + sg_bitmap_be *data = static_cast(malloc(sizeof(sg_bitmap_be))); result._data = data; @@ -1891,6 +2037,7 @@ sg_drawing_surface sgsdl2_load_bitmap(const char * filename) data->drawable = false; data->clipped = false; data->clip = {0,0,0,0}; + data->last_draw_loc = SG_BITMAP_NONE; result.kind = SGDS_Bitmap; result.width = surface->w; diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.h b/Backend/SGSDL2/src/SGSDL2Graphics.h index 3d105799..db96f0b2 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.h +++ b/Backend/SGSDL2/src/SGSDL2Graphics.h @@ -27,6 +27,13 @@ unsigned int _sgsdl2_renderer_count(sg_drawing_surface *surface); SDL_Renderer * _sgsdl2_prepared_renderer(sg_drawing_surface* surface, unsigned int idx); void _sgsdl2_complete_render(sg_drawing_surface* surface, unsigned int idx); +typedef enum sg_bitmap_draw_loc +{ + SG_BITMAP_TEXTURE, + SG_BITMAP_SURFACE, + SG_BITMAP_NONE +} sg_bitmap_draw_loc; + typedef struct sg_window_be { SDL_Window * window; @@ -44,12 +51,13 @@ typedef struct sg_window_be typedef struct sg_bitmap_be { // 1 texture per open window - SDL_Texture ** texture; - SDL_Surface * surface; - bool clipped; - SDL_Rect clip; + SDL_Texture ** texture; + SDL_Surface * surface; + sg_bitmap_draw_loc last_draw_loc; + bool clipped; + SDL_Rect clip; - bool drawable; // can be drawn on + bool drawable; // can be drawn on } sg_bitmap_be; diff --git a/Backend/Test/src/main.cpp b/Backend/Test/src/main.cpp index 59842305..d52a13e0 100644 --- a/Backend/Test/src/main.cpp +++ b/Backend/Test/src/main.cpp @@ -42,7 +42,7 @@ enum test_options enum test_drawing_options { - TEST_COLORS = 1, + TEST_COLORS = 1, TEST_READ_PIXELS = 2, TEST_POSITIONS = 4, TEST_ALPHA = 8, @@ -53,7 +53,9 @@ enum test_drawing_options TEST_LINES = 256, TEST_BITMAPS = 512, TEST_INPUT = 1024, - TEST_FULLSCREEN = 2048 + TEST_FULLSCREEN = 2048, + TEST_DIRECT_PIXSPEED = 4096, + TEST_BITMAP_PIXSPEED = 8192 }; void print_options() @@ -83,6 +85,8 @@ void print_drawing_options() cout << "512: test bitmaps " << endl; cout << "1024: test input " << endl; cout << "2048: test fullscreen " << endl; + cout << "4096: test direct pixel drawing speed " << endl; + cout << "8192: test bitmap pixel drawing speed " << endl; } @@ -408,8 +412,93 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); + _sg_functions->input.process_events(); + } +} + + +void test_direct_pixel_speed(sg_drawing_surface *window_arr, int sz) +{ + _sg_functions->input.process_events(); + for (int cnt = 0; cnt < 5; cnt++) + { + for (int w = 0; w < sz; w++) + { + float data[] = {0,0}; + + int start_time = _sg_functions->utils.get_ticks(); + for (int y = 0; y < 600; y++) + { + for (int x = 0; x < 800; x++) + { + data[0] = x; + data[1] = y; + _sg_functions->graphics.draw_pixel(&window_arr[w], {1.0,0,0,1.0}, data, 2 ); + } + } + + int end_time = _sg_functions->utils.get_ticks(); + + _sg_functions->input.process_events(); + refresh_or_draw(&window_arr[w]); + + cout << "Direct pixel drawing time for window " << w + << " was " << end_time - start_time << "ms" << endl; + } + } + cout << endl; +} + +void test_bitmap_pixel_speed(sg_drawing_surface *window_arr, int sz) +{ _sg_functions->input.process_events(); + for (int w = 0; w < sz; w++) + { + _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); + refresh_or_draw(&window_arr[w]); + _sg_functions->input.process_events(); + } + + _sg_functions->input.process_events(); + sg_drawing_surface bitmap = _sg_functions->image.create_bitmap(800, 600); + for (int cnt = 0; cnt < 5; cnt++) + { + for (int w = 0; w < sz; w++) + { + float data[2]; + int start_time = _sg_functions->utils.get_ticks(); + + _sg_functions->graphics.clear_drawing_surface( &bitmap, {1,1,1,1} ); + + for (int y = 0; y < 600; y++) + { + for (int x = 0; x < 800; x++) + { + data[0] = x; + data[1] = y; + _sg_functions->graphics.draw_pixel(&bitmap, {0,0,1,1}, data, 2 ); + } + } + + int mid_time = _sg_functions->utils.get_ticks(); + + float srcDat[] = { 0, 0, 0, 0, 0, 1, 1 }; + float dstDat[] = { 0, 0, 0, 0 }; + + _sg_functions->image.draw_bitmap(&bitmap, &window_arr[w],srcDat,7,dstDat,4,SG_FLIP_NONE); + + int end_time = _sg_functions->utils.get_ticks(); + + _sg_functions->input.process_events(); + refresh_or_draw(&window_arr[w]); + + cout << "Pixel drawing time to bitmap was " << mid_time - start_time << "ms" << endl; + cout << "Drawing time from bitmap to window " << w << " was " + << end_time - mid_time << "ms" << endl; + } } + _sg_functions->graphics.close_drawing_surface(&bitmap); + cout << endl; } @@ -927,7 +1016,7 @@ bool test_basic_drawing(int drawing_test_run) _sg_functions->graphics.show_fullscreen(&window, true); test_rects( &window, 1); - + _sg_functions->graphics.show_fullscreen(&window, false); } @@ -983,18 +1072,18 @@ bool test_window_operations() sg_drawing_surface w[2]; w[0] = _sg_functions->graphics.open_window("Window 1", 800, 600); w[1] = _sg_functions->graphics.open_window("Window 2", 300, 300); - + _sg_functions->input.move_window(&w[1], 0, 0); - + _sg_functions->graphics.show_border(&w[0], false); - + if ( w[0].width != 800 ) cout << " >> Error with w[0] width! " << w[0].width << endl; if ( w[1].width != 300 ) cout << " >> Error with w[1] width! " << w[1].width << endl; - + if ( w[0].height != 600 ) cout << " >> Error with w[0] height! " << w[0].height << endl; if ( w[1].height != 300 ) cout << " >> Error with w[1] height! " << w[1].height << endl; - + test_colors(w, 2); test_clip(w, 2); test_pixels(w, 2); @@ -1004,7 +1093,7 @@ bool test_window_operations() test_ellipses(w, 2); test_lines(w, 2); test_bitmaps(w, 2); - + test_input(w, 2); _sg_functions->graphics.close_drawing_surface(&w[0]); @@ -1174,7 +1263,7 @@ int main(int argc, const char * argv[]) int test_run = 0; int test_drawing_run = INT_MAX; scanf("%d", &test_run); - + if (test_run == 0) { test_run |= 255; @@ -1187,13 +1276,13 @@ int main(int argc, const char * argv[]) } output_system_details(); - + if (test_run & BASIC_DRAWING && ! test_draw_bitmap_without_window() ) { cout << "Drawing to bitmap without window failed..." << endl; return -1; } - + if (test_run & BASIC_DRAWING && ! test_basic_drawing(test_drawing_run) ) { cout << "Basic drawing failed with error: " << endl; @@ -1234,7 +1323,7 @@ int main(int argc, const char * argv[]) { test_text(); } - + if (test_run & NETWORK) { test_network(); From 2905cf78a24c6814e794a6af18f9dc31e43f3977 Mon Sep 17 00:00:00 2001 From: Aloz1 Date: Tue, 2 Aug 2016 09:10:41 +1000 Subject: [PATCH 2/6] Fixed pixel speed test in test files Speed tests were already partly implemented, but conditionals for selecting the tests based on input from the user must have been accidentally removed during rebase from v4 branch to devel. --- Backend/Test/src/main.cpp | 470 +++++++++++++++++++------------------- 1 file changed, 241 insertions(+), 229 deletions(-) diff --git a/Backend/Test/src/main.cpp b/Backend/Test/src/main.cpp index d52a13e0..c92f2828 100644 --- a/Backend/Test/src/main.cpp +++ b/Backend/Test/src/main.cpp @@ -29,64 +29,64 @@ sg_interface * _sg_functions = NULL; sg_drawing_surface img, img2; sg_drawing_surface bmp; -enum test_options -{ +enum test_options +{ BASIC_DRAWING = 1, - WINDOW_OPERATIONS = 2, - BITMAP_DRAWING = 4, + WINDOW_OPERATIONS = 2, + BITMAP_DRAWING = 4, AUDIO = 8, INPUT = 16, TEXT = 32, NETWORK = 64 -}; +}; -enum test_drawing_options +enum test_drawing_options { - TEST_COLORS = 1, - TEST_READ_PIXELS = 2, - TEST_POSITIONS = 4, - TEST_ALPHA = 8, - TEST_CLIP = 16, - TEST_PIXELS = 32, - TEST_SHAPES = 64, - TEST_RESIZE = 128, + TEST_COLORS = 1, + TEST_READ_PIXELS = 2, + TEST_POSITIONS = 4, + TEST_ALPHA = 8, + TEST_CLIP = 16, + TEST_PIXELS = 32, + TEST_SHAPES = 64, + TEST_RESIZE = 128, TEST_LINES = 256, - TEST_BITMAPS = 512, + TEST_BITMAPS = 512, TEST_INPUT = 1024, TEST_FULLSCREEN = 2048, TEST_DIRECT_PIXSPEED = 4096, TEST_BITMAP_PIXSPEED = 8192 }; -void print_options() +void print_options() { - cout << "0: all " << endl; - cout << "1: basic drawing functions" << endl; - cout << "2: window operations" << endl; - cout << "4: bitmap drawing" << endl; - cout << "8: audio " << endl; - cout << "16: input " << endl; + cout << "0: all " << endl; + cout << "1: basic drawing functions" << endl; + cout << "2: window operations" << endl; + cout << "4: bitmap drawing" << endl; + cout << "8: audio " << endl; + cout << "16: input " << endl; cout << "32: text " << endl; cout << "64: network " << endl; } -void print_drawing_options() +void print_drawing_options() { - cout << "0: all " << endl; - cout << "1: colors" << endl; - cout << "2: read pixels" << endl; - cout << "4: test positions" << endl; - cout << "8: test alpha" << endl; - cout << "16: test clip" << endl; - cout << "32 test pixels" << endl; - cout << "64: test shapes" << endl; - cout << "128: test resize " << endl; - cout << "256: test lines " << endl; - cout << "512: test bitmaps " << endl; - cout << "1024: test input " << endl; - cout << "2048: test fullscreen " << endl; - cout << "4096: test direct pixel drawing speed " << endl; - cout << "8192: test bitmap pixel drawing speed " << endl; + cout << "0: all " << endl; + cout << "1: colors" << endl; + cout << "2: read pixels" << endl; + cout << "4: test positions" << endl; + cout << "8: test alpha" << endl; + cout << "16: test clip" << endl; + cout << "32 test pixels" << endl; + cout << "64: test shapes" << endl; + cout << "128: test resize " << endl; + cout << "256: test lines " << endl; + cout << "512: test bitmaps " << endl; + cout << "1024: test input " << endl; + cout << "2048: test fullscreen " << endl; + cout << "4096: test direct pixel drawing speed " << endl; + cout << "8192: test bitmap pixel drawing speed " << endl; } @@ -95,21 +95,21 @@ void print_drawing_options() // and initialised? // bool test_core_functions() -{ +{ cout << "Testing Core Functions!" << endl; - + cout << "Calling load_sg..." << endl; _sg_functions = sg_load(get_input_callbacks()); - + if ( !_sg_functions ) { cout << "Failed to load functions!" << endl; return false; } - + cout << "Calling init..." << endl; _sg_functions->init(); - + return false == _sg_functions->has_error; } @@ -126,10 +126,10 @@ void refresh_or_draw(sg_drawing_surface *surf) // if we are refreshing a window... do normal processing if (surf->kind == SGDS_Window) { - _sg_functions->input.process_events(); + _sg_functions->input.process_events(); if (_sg_functions->input.window_close_requested(surf)) - { - exit(0); + { + exit(0); } _sg_functions->graphics.refresh_window(surf); @@ -150,7 +150,7 @@ void refresh_or_draw(sg_drawing_surface *surf) void test_colors(sg_drawing_surface *window_arr, int sz) { cout << "Testing Colors" << endl; - + for (int w = 0; w < sz; w++) { cout << " - Clearning the surface to..." << endl; @@ -158,22 +158,22 @@ void test_colors(sg_drawing_surface *window_arr, int sz) _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 0.0, 0.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(200); - + cout << " - WHITE" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(500); - + cout << " - GREEN" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 1.0, 0.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(200); - + cout << " - BLUE" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 0.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(200); - + cout << " - WHITE" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); @@ -184,22 +184,22 @@ void test_colors(sg_drawing_surface *window_arr, int sz) void test_read_pixels(sg_drawing_surface *window) { cout << "Testing Reading of Pixel data" << endl; - - + + _sg_functions->graphics.clear_drawing_surface(window, {1.0, 0.0, 0.0, 1.0}); sg_color clr = _sg_functions->graphics.read_pixel(window, 10, 10); - + cout << " - Color at 10,10 is RGBA " << clr.r << "," << clr.g << "," << clr.b << "," << clr.a << endl; cout << " - Match 1,0,0,1" << endl; - + clr = _sg_functions->graphics.read_pixel(window, -10, -10); cout << " - Color at -10,-10 is RGBA " << clr.r << "," << clr.g << "," << clr.b << "," << clr.a << endl; cout << " Match 0,0,0,0" << endl; - + _sg_functions->graphics.clear_drawing_surface(window, {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(window); clr = _sg_functions->graphics.read_pixel(window, 10, 10); - + cout << " - Color at 10,10 is RGBA " << clr.r << "," << clr.g << "," << clr.b << "," << clr.a << endl; cout << " - Match 1,1,1,1" << endl; } @@ -220,7 +220,7 @@ void test_rects(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -228,7 +228,7 @@ void test_rects(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_aabb_rect(&window_arr[w], random_color(), data, 4 ); @@ -240,7 +240,7 @@ void test_rects(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -248,57 +248,57 @@ void test_rects(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_aabb_rect(&window_arr[w], random_color(), data, 4 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float x, y; - + x = rand() / (float)RAND_MAX * 800; y = rand() / (float)RAND_MAX * 600; - + float data[] = { x, y, x + 100, y, x, y + 100, x + 100, y + 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_rect(&window_arr[w], random_color(), data, 8 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float x = rand() / (float)RAND_MAX * 800; float y = rand() / (float)RAND_MAX * 600; - + float data[] = { x, y, x + 100, y, x, y + 100, x + 100, y + 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_rect(&window_arr[w], random_color(), data, 8 ); @@ -318,7 +318,7 @@ void test_triangles(sg_drawing_surface *window_arr, int sz) refresh_or_draw(&window_arr[w]); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -328,19 +328,19 @@ void test_triangles(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_triangle(&window_arr[w], random_color(), data, 6 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -350,7 +350,7 @@ void test_triangles(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_triangle(&window_arr[w], random_color(), data, 6 ); @@ -369,7 +369,7 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) refresh_or_draw(&window_arr[w]); _sg_functions->input.process_events(); } - + _sg_functions->input.process_events(); for (int i = 0; i < SHAPE_COUNT; i++) { @@ -384,21 +384,21 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) _sg_functions->graphics.draw_pixel(&window_arr[w], clr, data, 2 ); } - + _sg_functions->input.process_events(); refresh_or_draw(&window_arr[w]); } } - + _sg_functions->input.process_events(); for (int w = 0; w < sz; w++) { sg_drawing_surface *wnd = &window_arr[w]; int sz = window_arr[w].width * window_arr[w].height; int pixels[sz]; - + _sg_functions->graphics.to_pixels(wnd, pixels, sz); - + int count = 0; for (int x = 0; x < window_arr[w].width; x++) { @@ -409,7 +409,7 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) _sg_functions->input.process_events(); } cout << "Window " << w << " has " << count << " white pixels" << endl; - + _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->input.process_events(); @@ -419,6 +419,7 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) void test_direct_pixel_speed(sg_drawing_surface *window_arr, int sz) { + cout << "Testing Direct pixel drawing speed" << endl; _sg_functions->input.process_events(); for (int cnt = 0; cnt < 5; cnt++) { @@ -442,15 +443,16 @@ void test_direct_pixel_speed(sg_drawing_surface *window_arr, int sz) _sg_functions->input.process_events(); refresh_or_draw(&window_arr[w]); - cout << "Direct pixel drawing time for window " << w + cout << " Direct pixel drawing time for window " << w << " was " << end_time - start_time << "ms" << endl; } - } + } cout << endl; } void test_bitmap_pixel_speed(sg_drawing_surface *window_arr, int sz) { + cout << "Testing bitmap pixel drawing speed" << endl; _sg_functions->input.process_events(); for (int w = 0; w < sz; w++) { @@ -458,7 +460,7 @@ void test_bitmap_pixel_speed(sg_drawing_surface *window_arr, int sz) refresh_or_draw(&window_arr[w]); _sg_functions->input.process_events(); } - + _sg_functions->input.process_events(); sg_drawing_surface bitmap = _sg_functions->image.create_bitmap(800, 600); for (int cnt = 0; cnt < 5; cnt++) @@ -492,8 +494,8 @@ void test_bitmap_pixel_speed(sg_drawing_surface *window_arr, int sz) _sg_functions->input.process_events(); refresh_or_draw(&window_arr[w]); - cout << "Pixel drawing time to bitmap was " << mid_time - start_time << "ms" << endl; - cout << "Drawing time from bitmap to window " << w << " was " + cout << " Pixel drawing time to bitmap was " << mid_time - start_time << "ms" << endl; + cout << " Drawing time from bitmap to window " << w << " was " << end_time - mid_time << "ms" << endl; } } @@ -508,33 +510,33 @@ void test_circles(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_circle(&window_arr[w], random_color(), data, 3 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_circle(&window_arr[w], random_color(), data, 3 ); @@ -549,7 +551,7 @@ void test_ellipses(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -557,19 +559,19 @@ void test_ellipses(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_ellipse(&window_arr[w], random_color(), data, 4 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -577,7 +579,7 @@ void test_ellipses(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_ellipse(&window_arr[w], random_color(), data, 4 ); @@ -592,7 +594,7 @@ void test_lines(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -601,7 +603,7 @@ void test_lines(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 600, 1 + rand() / (float)RAND_MAX * 30 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_line(&window_arr[w], random_color(), data, 5 ); @@ -613,34 +615,34 @@ void test_lines(sg_drawing_surface *window_arr, int sz) void test_clip(sg_drawing_surface *window_arr, int sz) { cout << "Testing Clipping" << endl; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 0.0, 1.0, 1.0}); - + float data[] = { 0.0f, 0.0f, window_arr[w].width * 0.9f, window_arr[w].height * 0.9f }; - + for (int c = 0; c < 8; c++) { data[2] = window_arr[w].width * (0.9 - c * 0.1); data[3] = window_arr[w].height * (0.9 - c * 0.1); - + _sg_functions->graphics.set_clip_rect(&window_arr[w], data, 4); _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0f - c * 0.1f, 0.0, 0.0, 1.0}); } refresh_or_draw(&window_arr[w]); - + data[2] = window_arr[w].width * 0.4; data[3] = window_arr[w].height * 0.4; _sg_functions->graphics.set_clip_rect(&window_arr[w], data, 4); _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 1.0f, 0.0, 1.0f}); } - + _sg_functions->utils.delay(3000); - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_clip_rect(&window_arr[w]); @@ -653,22 +655,22 @@ bool test_positions(sg_drawing_surface *window_arr, int sz) for (int i = 0; i < sz; i++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1.0, 1.0, 1.0, 1.0}); - + float data[] = {0.0f, 0.0f, 50.0f, 50.0f}; float data1[] = {window_arr[i].width - 50.0f, 0.0f, 50.0f, 50.0f}; float data2[] = {0.0f, window_arr[i].height - 50.0f, 50.0f, 50.0f}; float data3[] = {window_arr[i].width - 50.0f, window_arr[i].height - 50.0f, 50.0f, 50.0f}; - + _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {1.0f, 0.0f, 0.0f, 1.0f}, data, 4); _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {0.0f, 1.0f, 0.0f, 1.0f}, data1, 4); _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {0.0f, 0.0f, 1.0f, 1.0f}, data2, 4); _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {0.0f, 0.0f, 0.0f, 1.0f}, data3, 4); - + refresh_or_draw(&window_arr[i]); } _sg_functions->utils.delay(2000); - + return true; } @@ -677,7 +679,7 @@ bool test_alpha(sg_drawing_surface *window_arr, int sz) for (int i = 0; i < sz; i++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1.0, 1.0, 1.0, 1.0}); - + float data[] = {0.0f, 0.0f, window_arr[i].width / 11.0f, window_arr[i].height * 1.0f}; for (int j = 0; j < 11; j++) @@ -685,12 +687,12 @@ bool test_alpha(sg_drawing_surface *window_arr, int sz) data[0] = j * data[2]; _sg_functions->graphics.fill_ellipse(&window_arr[i], {1.0f, 0.0f, 0.0f, 0.1f * j}, data, 4); } - + refresh_or_draw(&window_arr[i]); } - + _sg_functions->utils.delay(2000); - + return true; } @@ -702,12 +704,12 @@ void test_resize(sg_drawing_surface * window_arr, int sz) int w, h; w = window_arr[i].width; h = window_arr[i].height; - + _sg_functions->graphics.resize(&window_arr[i], 320, 240); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); - + _sg_functions->graphics.resize(&window_arr[i], 640, 480); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); @@ -717,14 +719,14 @@ void test_resize(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); - + _sg_functions->graphics.resize(&window_arr[i], 1024, 768); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); - + _sg_functions->graphics.resize(&window_arr[i], w, h); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1.0f, 1.0f, 1.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window_arr[i]); @@ -738,7 +740,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) float src_data[] = {0, 0, static_cast(img.width), static_cast(img.height)}; float bmp_src_data[] = {0, 0, static_cast(bmp.width), static_cast(bmp.height)}; float dst_data[] = {0, 0, 0, 0, 0, 1, 1}; - + //Draw at TOP LEFT (shows that the scaling of the draw coordinates works) for (int i = 0; i < sz; i++) { @@ -747,15 +749,15 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->image.draw_bitmap( &bmp, &window_arr[i], bmp_src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(5000); - + _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); } - + dst_data[0] = 300.0f; dst_data[1] = 300.0f; - + //Test rotation (should rotate around centre) for (int u = 0; u <= 360; u += 4) { @@ -763,12 +765,12 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) { //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); - + dst_data[2] = static_cast(u); - + _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->image.draw_bitmap( &img2, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); - _sg_functions->graphics.refresh_window(&window_arr[i]); + _sg_functions->graphics.refresh_window(&window_arr[i]); } } _sg_functions->utils.delay(200); @@ -776,9 +778,9 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) dst_data[0] = 150.0f; dst_data[1] = 150.0f; dst_data[2] = 0; - + //Test scale - for (int u = 0; u <= 90; u++) + for (int u = 0; u <= 90; u++) { for (int i = 0; i < sz; i++) { @@ -793,9 +795,9 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + //Test rotate and scale (should rotate around centre) - for (int u = 0; u <= 360; u += 2) + for (int u = 0; u <= 360; u += 2) { for (int i = 0; i < sz; i++) { @@ -819,7 +821,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) dst_data[2] = static_cast(u * 2); dst_data[5] = static_cast(u / 360.0); dst_data[6] = static_cast((720 - u) / 360.0); - + //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); @@ -836,7 +838,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) dst_data[2] = static_cast(u * 2); dst_data[5] = static_cast(u / 360.0); dst_data[6] = static_cast((720 - u) / 360.0); - + //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); @@ -844,11 +846,11 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + dst_data[2] = 0; dst_data[5] = 1; dst_data[6] = 1; - + //Test flip for (int u = 0; u < 240; u++) { @@ -861,7 +863,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + //Test pretty // double scale; for (int u = 0; u <= 720; u += 4) @@ -870,18 +872,18 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) { // scale = sin(u/90.0) + 0.5; // scale = scale > 0.2 ? scale : 0.2; - + dst_data[2] = u; dst_data[3] = 100 + sin(u/60.0)*100; dst_data[4] = -u; - + //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); - _sg_functions->graphics.refresh_window(&window_arr[i]); + _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + _sg_functions->utils.delay(300); _sg_functions->input.process_events(); } @@ -891,19 +893,19 @@ bool test_draw_bitmap_without_window() sg_drawing_surface window; cout << "Creating bitmap" << endl; - + bmp = _sg_functions->image.create_bitmap(100, 100); cout << "Drawing to bitmap" << endl; - + _sg_functions->graphics.clear_drawing_surface(&bmp, {1.0f, 0.0f, 0.0f, 1.0f}); float data_t[] = {0.0f, 99.0f, 99.0f, 99.0f, 50.0f, 1.0f}; _sg_functions->graphics.fill_triangle(&bmp, {1.0,1.0,1.0,1.0}, data_t, 6 ); - + float data[] = {0.0f, 20.0f, 80.0f, 20.0f}; _sg_functions->graphics.fill_aabb_rect(&bmp, {0.0f, 1.0f, 0.0f, 1.0f}, data, 4); - + data[1] = 40.0f; data[2] = 60.0f; _sg_functions->graphics.fill_aabb_rect(&bmp, {0.0f, 0.0f, 1.0f, 1.0f}, data, 4); @@ -917,7 +919,7 @@ bool test_draw_bitmap_without_window() _sg_functions->graphics.fill_aabb_rect(&bmp, {1.0f, 1.0f, 0.0f, 1.0f}, data, 4); cout << "Saving bitmap" << endl; - + #ifdef WINDOWS _sg_functions->graphics.save_png(&bmp, "c:\\Users\\acain\\Desktop\\test1.png"); #else @@ -925,35 +927,35 @@ bool test_draw_bitmap_without_window() #endif float src_data[] = {0, 0, static_cast(bmp.width), static_cast(bmp.height)}; float dst_data[] = {0, 0, 0, 0, 0, 1, 1}; - + window = _sg_functions->graphics.open_window("Test Bitmap Drawing", 600, 600); _sg_functions->graphics.clear_drawing_surface(&window, {0.0f, 0.0f, 0.0f, 1.0f}); _sg_functions->image.draw_bitmap( &bmp, &window, src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window); - + _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + #ifdef WINDOWS _sg_functions->graphics.save_png(&window, "c:\\Users\\acain\\Desktop\\test2.png"); #else _sg_functions->graphics.save_png(&window, "/Users/acain/Desktop/test2.png"); -#endif +#endif sg_color clr = _sg_functions->graphics.read_pixel(&bmp, 5, 5); cout << "Bmp Color is : " << clr.r << ":" << clr.g << ":" << clr.b << ":" << clr.a << endl; clr = _sg_functions->graphics.read_pixel(&window, 0, 0); cout << "Wnd Color is : " << clr.r << ":" << clr.g << ":" << clr.b << ":" << clr.a << endl; - + _sg_functions->graphics.close_drawing_surface(&window); - + #ifdef WINDOWS _sg_functions->graphics.save_png(&bmp, "c:\\Users\\acain\\Desktop\\test3.png"); -#else +#else _sg_functions->graphics.save_png(&bmp, "/Users/acain/Desktop/test3.png"); #endif - + window = _sg_functions->graphics.open_window("Draw in new window!", 600, 600); _sg_functions->input.process_events(); @@ -961,7 +963,7 @@ bool test_draw_bitmap_without_window() _sg_functions->image.draw_bitmap( &bmp, &window, src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.close_drawing_surface(&window); return true; @@ -970,8 +972,8 @@ bool test_draw_bitmap_without_window() bool test_basic_drawing(int drawing_test_run) { cout << "Testing Basic Drawing!" << endl; - cout << drawing_test_run << endl; - + cout << drawing_test_run << endl; + sg_drawing_surface window; window = _sg_functions->graphics.open_window("Test Basic Drawing", 800, 600); @@ -980,38 +982,38 @@ bool test_basic_drawing(int drawing_test_run) img2 = _sg_functions->image.create_bitmap(100, 50); _sg_functions->graphics.clear_drawing_surface(&img2, {1.0f, 0.0f, 0.0f, 1.0f}); - - if (drawing_test_run & TEST_COLORS) + + if (drawing_test_run & TEST_COLORS) { test_colors(&window, 1); } - if (drawing_test_run & TEST_PIXELS) + if (drawing_test_run & TEST_PIXELS) { test_read_pixels(&window); } - if (drawing_test_run & TEST_POSITIONS) + if (drawing_test_run & TEST_POSITIONS) { test_positions(&window, 1); } - if (drawing_test_run & TEST_ALPHA) + if (drawing_test_run & TEST_ALPHA) { test_alpha(&window, 1); } - if (drawing_test_run & TEST_CLIP) + if (drawing_test_run & TEST_CLIP) { test_clip( &window, 1); } - - if (drawing_test_run & TEST_PIXELS) + + if (drawing_test_run & TEST_PIXELS) { test_pixels( &window, 1); } - - if (drawing_test_run & TEST_FULLSCREEN) + + if (drawing_test_run & TEST_FULLSCREEN) { _sg_functions->graphics.show_fullscreen(&window, true); @@ -1019,28 +1021,28 @@ bool test_basic_drawing(int drawing_test_run) _sg_functions->graphics.show_fullscreen(&window, false); } - - if (drawing_test_run & TEST_SHAPES) + + if (drawing_test_run & TEST_SHAPES) { test_triangles( &window, 1); } - if (drawing_test_run & TEST_SHAPES) + if (drawing_test_run & TEST_SHAPES) { test_circles( &window, 1); } - - if (drawing_test_run & TEST_RESIZE) + + if (drawing_test_run & TEST_RESIZE) { test_resize(&window, 1); } - - if (drawing_test_run & TEST_SHAPES) + + if (drawing_test_run & TEST_SHAPES) { test_ellipses( &window, 1); } - if (drawing_test_run & TEST_LINES) + if (drawing_test_run & TEST_LINES) { test_lines( &window, 1); } @@ -1053,14 +1055,24 @@ bool test_basic_drawing(int drawing_test_run) _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 1.0f, 1.0f, 1.0f}); test_bitmaps( &window, 1); } - - if (drawing_test_run & TEST_INPUT) + + if (drawing_test_run & TEST_INPUT) { test_input(&window, 1); } + if (drawing_test_run & TEST_DIRECT_PIXSPEED) + { + test_direct_pixel_speed(&window, 1); + } + + if (drawing_test_run & TEST_BITMAP_PIXSPEED) + { + test_bitmap_pixel_speed(&window, 1); + } + _sg_functions->graphics.close_drawing_surface(&window); - + return false == _sg_functions->has_error; } @@ -1068,7 +1080,7 @@ bool test_window_operations() { cout << "Testing Window Operations!" << endl; _sg_functions->input.process_events(); - + sg_drawing_surface w[2]; w[0] = _sg_functions->graphics.open_window("Window 1", 800, 600); w[1] = _sg_functions->graphics.open_window("Window 2", 300, 300); @@ -1105,51 +1117,51 @@ bool test_window_operations() bool test_bitmap_dest_drawing() { cout << "Testing Drawing to Bitmap!" << endl; - + sg_drawing_surface window; window = _sg_functions->graphics.open_window("Drawing to Bitmap", 800, 600); _bmp_wnd = &window; - + sg_drawing_surface bmp = _sg_functions->image.create_bitmap(640, 480); - + float src_data[] = {0, 0, static_cast(img.width), static_cast(img.height)}; float dst_data[] = {0, 0, 0, 0, 0, 1, 1}; - + _sg_functions->image.draw_bitmap( &img, &bmp, src_data, 4, dst_data, 7, SG_FLIP_NONE); - + refresh_or_draw(&bmp); _sg_functions->utils.delay(3000); - + test_colors(&bmp, 1); test_positions(&bmp, 1); test_alpha(&bmp, 1); - + test_clip( &bmp, 1); test_pixels( &bmp, 1); - + test_rects( &bmp, 1); - + test_triangles( &bmp, 1); test_circles( &bmp, 1); - + test_ellipses( &bmp, 1); test_lines( &bmp, 1); dst_data[0] = 50; dst_data[1] = 50; - + src_data[2] = img2.width; src_data[3] = img2.height; - - + + _sg_functions->image.draw_bitmap( &img, &bmp, src_data, 4, dst_data, 7, SG_FLIP_NONE); refresh_or_draw(&bmp); _sg_functions->utils.delay(3000); - + _sg_functions->graphics.close_drawing_surface(&bmp); _sg_functions->graphics.close_drawing_surface(&window); _bmp_wnd = NULL; - + return false == _sg_functions->has_error; } @@ -1158,11 +1170,11 @@ void test_bitmap_loading_saving() sg_drawing_surface lines = _sg_functions->image.load_bitmap("Lines.png"); int sz = lines.width * lines.height; int pixels[sz]; - + for (int i = 0; i < sz; i++) pixels[i] = 0; - + _sg_functions->graphics.to_pixels(&lines, pixels, sz); - + for (int i = 0; i < sz; i++) { cout << std::hex << pixels[i] << std::dec << " "; @@ -1171,12 +1183,12 @@ void test_bitmap_loading_saving() cout << endl; } } - + sg_color clr = _sg_functions->graphics.read_pixel(&lines, 0, 0); cout << "Lines color is : " << clr.r << ":" << clr.g << ":" << clr.b << ":" << clr.a << endl; - + _sg_functions->graphics.save_png(&lines, "/Users/acain/Desktop/test.png"); - + _sg_functions->graphics.close_drawing_surface(&lines); } @@ -1184,9 +1196,9 @@ void test_bitmap_loading_saving() void output_system_details() { sg_system_data *data = _sg_functions->read_system_data(); - + cout << "Display count: " << data->num_displays << endl; - + for (int i = 0; i < data->num_displays; i++) { cout << " -> Display[" << i << "] = " << data->displays[i].name << endl; @@ -1197,7 +1209,7 @@ void output_system_details() cout << " " << data->displays[i].modes[m].width << " x " << data->displays[i].modes[m].height << endl; } } - + cout << "Time is " << _sg_functions->utils.get_ticks() << endl; } @@ -1205,41 +1217,41 @@ void test_fullscreen() { cout << "Calling load_sg..." << endl; _sg_functions = sg_load(get_input_callbacks()); - + if ( !_sg_functions ) { cout << "Failed to load functions!" << endl; return; } - + cout << "Calling init..." << endl; _sg_functions->init(); sg_drawing_surface window; window = _sg_functions->graphics.open_window("Test Basic Drawing", 800, 600); - + _sg_functions->graphics.show_fullscreen(&window, false); - + _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 1.0f, 1.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window); _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.show_fullscreen(&window, true); - + // test_rects( &window, 1); _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 1.0f, 1.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window); _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.show_fullscreen(&window, false); - + _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 0.0f, 0.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window); _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.close_drawing_surface(&window); } @@ -1257,22 +1269,22 @@ int main(int argc, const char * argv[]) test_bitmap_loading_saving(); - cout << " Which tests do you want to run? " << endl; - print_options(); + cout << " Which tests do you want to run? " << endl; + print_options(); - int test_run = 0; - int test_drawing_run = INT_MAX; + int test_run = 0; + int test_drawing_run = INT_MAX; scanf("%d", &test_run); - if (test_run == 0) + if (test_run == 0) { - test_run |= 255; + test_run |= 255; } - else if (test_run & BASIC_DRAWING) + else if (test_run & BASIC_DRAWING) { - cout << "Which drawing functions would you like to run? " << endl; - print_drawing_options(); - scanf("%d", &test_drawing_run); + cout << "Which drawing functions would you like to run? " << endl; + print_drawing_options(); + scanf("%d", &test_drawing_run); } output_system_details(); @@ -1289,25 +1301,25 @@ int main(int argc, const char * argv[]) //cout << _sg_functions->current_error << endl; return -1; } - + _sg_functions->input.process_events(); - - if (test_run & WINDOW_OPERATIONS) + + if (test_run & WINDOW_OPERATIONS) { test_window_operations(); } - - if (test_run & BITMAP_DRAWING) + + if (test_run & BITMAP_DRAWING) { test_bitmap_dest_drawing(); test_bitmap_loading_saving(); } - + _sg_functions->graphics.close_drawing_surface(&img); _sg_functions->graphics.close_drawing_surface(&img2); - - if (test_run & AUDIO) + + if (test_run & AUDIO) { test_audio(); } @@ -1319,7 +1331,7 @@ int main(int argc, const char * argv[]) test_input(w, 1); } - if (test_run & TEXT) + if (test_run & TEXT) { test_text(); } @@ -1328,10 +1340,10 @@ int main(int argc, const char * argv[]) { test_network(); } - + _sg_functions->finalise(); cout << "Success" << endl; - + return 0; } From 15179678bd1b9a7ba50d136054c7ffdc16778bf9 Mon Sep 17 00:00:00 2001 From: Aloz1 Date: Thu, 4 Aug 2016 09:39:29 +1000 Subject: [PATCH 3/6] Refactored code to better suit rebase. As bitmaps now always have an allocated surface, there is no need to ensure the surface exists. Surfaces are now also always drawable (which means that bitmap_be.drawable is probably no longer needed. This was done because it seemed the only reason surfaces were not drawable because of images that had been loaded from file which needed to be kept in sync with their textures. My modifications now no longer make this a problem as data will always be synced between surfaces when different drawing operations call for it. --- Backend/SGSDL2/src/SGSDL2Graphics.cpp | 335 +++++++++----------------- Backend/Test/src/main.cpp | 12 +- 2 files changed, 121 insertions(+), 226 deletions(-) diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.cpp b/Backend/SGSDL2/src/SGSDL2Graphics.cpp index 379d62e2..06d27315 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.cpp +++ b/Backend/SGSDL2/src/SGSDL2Graphics.cpp @@ -98,44 +98,6 @@ void _sgsdl2_set_renderer_target(unsigned int window_idx, sg_bitmap_be *target) } } -void _sgsdl2_make_drawable(sg_bitmap_be *bitmap) -{ - // recreate all textures with target access - - int access, w, h; - - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) - { - SDL_Renderer *renderer = _sgsdl2_open_windows[i]->renderer; - - SDL_Texture *orig_tex = bitmap->texture[i]; - - SDL_QueryTexture(orig_tex, NULL, &access, &w, &h); - - if ( access == SDL_TEXTUREACCESS_TARGET ) continue; // already target - - // Create new texture - SDL_Texture *tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h); - bitmap->texture[i] = tex; - - // Draw onto new texture - SDL_SetRenderTarget(renderer, tex); - SDL_RenderCopy(renderer, orig_tex, NULL, NULL); - - // Destroy old - SDL_DestroyTexture(orig_tex); - - _sgsdl2_restore_default_render_target(_sgsdl2_open_windows[i], bitmap); - } - - // Remove surface - SDL_FreeSurface(bitmap->surface); - bitmap->surface = NULL; - - // Set drawable - bitmap->drawable = true; -} - //-------------------------------------------------------------------------------------- // @@ -353,82 +315,69 @@ void _sgsdl2_get_pixels_from_renderer(SDL_Renderer *renderer, int x, int y, int free(raw_pixels); } -void _sgsdl2_bitmap_be_texture_to_pixels(sg_bitmap_be *bitmap_be, int *pixels, int sz, int w, int h) +void _sgsdl2_bitmap_be_texture_to_surface(sg_bitmap_be *bitmap) { - if (bitmap_be->drawable && _sgsdl2_num_open_windows > 0) + if (bitmap && (bitmap->last_draw_loc == SG_BITMAP_TEXTURE) && (_sgsdl2_num_open_windows > 0)) { - // read pixels from the texture - _sgsdl2_set_renderer_target(0, bitmap_be); - _sgsdl2_get_pixels_from_renderer(_sgsdl2_open_windows[0]->renderer, 0, 0, w, h, pixels); - _sgsdl2_restore_default_render_target(_sgsdl2_open_windows[0], bitmap_be); + SDL_Rect rect = {0, 0, bitmap->surface->w, bitmap->surface->h}; + _sgsdl2_set_renderer_target(0, bitmap); + + SDL_RenderReadPixels( + _sgsdl2_open_windows[0]->renderer, + &rect, + SDL_PIXELFORMAT_RGBA8888, + bitmap->surface->pixels, + bitmap->surface->w * 4 + ); + + bitmap->last_draw_loc = SG_BITMAP_NONE; } - else +} + +void _sgsdl2_texture_to_surface(sg_drawing_surface *drawing) +{ + if (drawing && (_sgsdl2_num_open_windows > 0)) { - // cannot read pixels ... make black image - for (int i = 0; i < sz; i++) { - pixels[i] = 255; - } + _sgsdl2_bitmap_be_texture_to_surface(static_cast(drawing->_data)); } } -void _sgsdl2_restore_surfaces() +void _sgsdl2_bitmaps_to_surface() { - Uint32 rmask, gmask, bmask, amask; - - /* SDL interprets each pixel as a 32-bit number, so our masks must depend - on the endianness (byte order) of the machine */ -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; -#else - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; -#endif - for (uint i = 0; i < _sgsdl2_num_open_bitmaps; i++) { - if ( ! _sgsdl2_open_bitmaps[i]->surface ) - { - int w, h; - SDL_QueryTexture(_sgsdl2_open_bitmaps[i]->texture[0], NULL, NULL, &w, &h); - - int sz = 4 * w * h; - int pixels[w * h]; - -// std::cout << "sz = " << sz << " size of pixels = " << sizeof(pixels) << std::endl; - - memset(pixels, 0, sizeof(pixels)); - - _sgsdl2_bitmap_be_texture_to_pixels(_sgsdl2_open_bitmaps[i], pixels, sz, w, h); - - _sgsdl2_open_bitmaps[i]->surface = SDL_CreateRGBSurface(0, w, h, 32, rmask, gmask, bmask, amask); + _sgsdl2_bitmap_be_texture_to_surface(_sgsdl2_open_bitmaps[i]); + } +} - SDL_LockSurface(_sgsdl2_open_bitmaps[i]->surface); +void _sgsdl2_bitmap_be_surface_to_texture(sg_bitmap_be *bitmap) +{ + if (bitmap && (bitmap->last_draw_loc == SG_BITMAP_SURFACE) && (_sgsdl2_num_open_windows > 0)) + { + for( Uint32 i = 0; i < _sgsdl2_num_open_windows; i++ ) + { + SDL_UpdateTexture( + bitmap->texture[i], + NULL, + bitmap->surface->pixels, + bitmap->surface->pitch + ); + } - int x = 0, y = 0; - int *p = (int*)_sgsdl2_open_bitmaps[i]->surface->pixels; - for (int px = 0; px < (w * h); px++) - { - p[x + (y * _sgsdl2_open_bitmaps[i]->surface->pitch / 4)] = pixels[px]; -// std::cout << "Set pixel[" << x <<","<surface->pitch / 4) << " = " << p[x + (y * _sgsdl2_open_bitmaps[i]->surface->pitch / 4)] << " " << pixels[px] << std::endl; + bitmap->last_draw_loc = SG_BITMAP_NONE; + } +} - x++; - if ( x >= w ) - { - x = 0; - y++; - } - } - SDL_UnlockSurface(_sgsdl2_open_bitmaps[i]->surface); - } +void _sgsdl2_surface_to_texture(sg_drawing_surface *drawing) +{ + if (drawing && (_sgsdl2_num_open_windows > 0)) + { + _sgsdl2_bitmap_be_surface_to_texture(static_cast(drawing->_data)); } } + void _sgsdl2_remove_window(sg_window_be * window_be) { unsigned int idx = window_be->idx; @@ -441,7 +390,7 @@ void _sgsdl2_remove_window(sg_window_be * window_be) if ( _sgsdl2_num_open_windows == 1 && _sgsdl2_has_open_bitmap_without_surface() ) { // Need to keep a window open to retain the bitmap surface - _sgsdl2_restore_surfaces(); + _sgsdl2_bitmaps_to_surface(); } // Remove all of the textures for this window @@ -900,8 +849,6 @@ void _sgsdl2_clear_bitmap(sg_drawing_surface *bitmap, sg_color clr) if ( bitmap_be ) { - if ( ! bitmap_be->drawable ) _sgsdl2_make_drawable( bitmap_be ); - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) { sg_window_be *window = _sgsdl2_open_windows[i]; @@ -918,60 +865,6 @@ void _sgsdl2_clear_bitmap(sg_drawing_surface *bitmap, sg_color clr) } } -void _sgsdl2_texture_to_surface(sg_drawing_surface *surface) -{ - if( surface && surface->kind == SGDS_Bitmap ) - { - sg_bitmap_be *bitmap_be= static_cast(surface->_data); - - if( bitmap_be->last_draw_loc != SG_BITMAP_TEXTURE ) return; - - SDL_Rect rect = {0, 0, surface->width, surface->height}; - _sgsdl2_set_renderer_target(0, bitmap_be); - - SDL_RenderReadPixels( - _sgsdl2_open_windows[0]->renderer, - &rect, - SDL_PIXELFORMAT_RGBA8888, - bitmap_be->surface->pixels, - surface->width * 4 - ); - - bitmap_be->last_draw_loc = SG_BITMAP_NONE; - } -} - -void _sgsdl2_surface_to_texture(sg_drawing_surface *surface) -{ - if( surface && surface->kind == SGDS_Bitmap ) - { - sg_bitmap_be *bitmap_be = static_cast(surface->_data); - - if( bitmap_be->last_draw_loc != SG_BITMAP_SURFACE ) return; - - Uint32 count = _sgsdl2_renderer_count( surface ); - for( Uint32 i = 0; i < count; i++ ) - { - /* - SDL_UpdateTexture( - bitmap_be->texture[i], - NULL, - bitmap_be->surface->pixels, - bitmap_be->surface->pitch - ); - */ - SDL_UpdateTexture( - bitmap_be->texture[i], - NULL, - bitmap_be->surface->pixels, - bitmap_be->surface->pitch - ); - } - - bitmap_be->last_draw_loc = SG_BITMAP_NONE; - } -} - void sgsdl2_clear_drawing_surface(sg_drawing_surface *surface, sg_color clr) { if ( ! surface ) return; @@ -1027,7 +920,6 @@ SDL_Renderer * _sgsdl2_prepared_renderer(sg_drawing_surface *surface, unsigned i case SGDS_Bitmap: { sg_bitmap_be *bitmap_be = static_cast(surface->_data); - if ( ! bitmap_be->drawable ) _sgsdl2_make_drawable( bitmap_be ); _sgsdl2_set_renderer_target(idx, bitmap_be); if (idx < _sgsdl2_num_open_windows) @@ -1087,10 +979,10 @@ void sgsdl2_draw_aabb_rect(sg_drawing_surface *surface, sg_color clr, float *dat static_cast(data[3]) }; + unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; - - unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) { @@ -1118,10 +1010,10 @@ void sgsdl2_fill_aabb_rect(sg_drawing_surface *surface, sg_color clr, float *dat static_cast(data[3]) }; + unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; - - unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) { @@ -1157,12 +1049,12 @@ void sgsdl2_draw_rect(sg_drawing_surface *surface, sg_color clr, float *data, in int x2 = static_cast(data[2]), y2 = static_cast(data[3]); int x3 = static_cast(data[4]), y3 = static_cast(data[5]); int x4 = static_cast(data[6]), y4 = static_cast(data[7]); - - _sgsdl2_surface_to_texture(surface); - static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1206,12 +1098,12 @@ void sgsdl2_fill_rect(sg_drawing_surface *surface, sg_color clr, float *data, in y[1] = static_cast(data[3]); y[2] = static_cast(data[7]); // Swap last 2 for SDL_gfx order y[3] = static_cast(data[5]); - - _sgsdl2_surface_to_texture(surface); - static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1248,12 +1140,12 @@ void sgsdl2_draw_triangle(sg_drawing_surface *surface, sg_color clr, float *data int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int x2 = static_cast(data[2]), y2 = static_cast(data[3]); int x3 = static_cast(data[4]), y3 = static_cast(data[5]); - - _sgsdl2_surface_to_texture(surface); - static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1280,11 +1172,11 @@ void sgsdl2_fill_triangle(sg_drawing_surface *surface, sg_color clr, float *data float x2 = data[2], y2 = data[3]; float x3 = data[4], y3 = data[5]; + unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; - unsigned int count = _sgsdl2_renderer_count(surface); - for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1319,12 +1211,12 @@ void sgsdl2_draw_ellipse(sg_drawing_surface *surface, sg_color clr, float *data, // 4 values = 1 point w + h int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int w = static_cast(data[2]), h = static_cast(data[3]); - - _sgsdl2_surface_to_texture(surface); - static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1354,12 +1246,12 @@ void sgsdl2_fill_ellipse(sg_drawing_surface *surface, sg_color clr, float *data, // 4 values = 1 point w + h int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int w = static_cast(data[2]), h = static_cast(data[3]); - - _sgsdl2_surface_to_texture(surface); - static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1399,9 +1291,9 @@ void sgsdl2_draw_pixel(sg_drawing_surface *surface, sg_color clr, float *data, i sg_bitmap_be *bitmap_be = static_cast(surface->_data); _sgsdl2_texture_to_surface(surface); + bitmap_be->last_draw_loc = SG_BITMAP_SURFACE; _set_pixel(bitmap_be->surface, clr, x1, y1); - bitmap_be->last_draw_loc = SG_BITMAP_SURFACE; return; } @@ -1476,10 +1368,10 @@ void sgsdl2_draw_circle(sg_drawing_surface *surface, sg_color clr, float *data, int x1 = static_cast(data[0]), y1 = static_cast(data[1]); int r = static_cast(data[2]); + unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; - - unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) { @@ -1516,6 +1408,9 @@ void sgsdl2_fill_circle(sg_drawing_surface *surface, sg_color clr, float *data, unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1559,11 +1454,11 @@ void sgsdl2_draw_line(sg_drawing_surface *surface, sg_color clr, float *data, in if ( w == 0 ) return; + unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; - unsigned int count = _sgsdl2_renderer_count(surface); - for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1696,7 +1591,7 @@ void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz) if ( ! surface || ! surface->_data || surface->width * surface->height != sz) return; SDL_Rect rect = {0, 0, surface->width, surface->height}; - + switch (surface->kind) { case SGDS_Window: @@ -1713,7 +1608,7 @@ void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz) case SGDS_Bitmap: { sg_bitmap_be * bitmap_be = static_cast(surface->_data); - + _sgsdl2_texture_to_surface(surface); for (int y = 0; y < surface->height; y++) @@ -1965,7 +1860,7 @@ void sgsdl2_load_graphics_fns(sg_interface * functions) sg_drawing_surface sgsdl2_create_bitmap(int width, int height) { internal_sgsdl2_init(); - if ( _sgsdl2_num_open_windows == 0 ) _sgsdl2_create_initial_window(); + //if ( _sgsdl2_num_open_windows == 0 ) _sgsdl2_create_initial_window(); sg_drawing_surface result = { SGDS_Unknown, 0, 0, NULL }; @@ -1979,26 +1874,34 @@ sg_drawing_surface sgsdl2_create_bitmap(int width, int height) data->clipped = false; data->clip = {0, 0, width, height}; - data->last_draw_loc = SG_BITMAP_NONE; + data->drawable = true; - data->surface = NULL; - data->texture = static_cast(malloc(sizeof(SDL_Texture*) * _sgsdl2_num_open_windows)); + data->last_draw_loc = SG_BITMAP_NONE; - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) + data->surface = SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0xff0000, 0xff00, 0xff); + _sgsdl2_clear_sdl_surface(data->surface,{0xff, 0xff, 0xff, 0xff}); + + + if (_sgsdl2_num_open_windows > 0) { - data->texture[i] = SDL_CreateTexture(_sgsdl2_open_windows[i]->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); + data->texture = static_cast(malloc(sizeof(SDL_Texture*) * _sgsdl2_num_open_windows)); - SDL_SetTextureBlendMode(data->texture[i], SDL_BLENDMODE_BLEND); + for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) + { + data->texture[i] = SDL_CreateTexture(_sgsdl2_open_windows[i]->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); - _sgsdl2_set_renderer_target(i, data); - SDL_SetRenderDrawColor(_sgsdl2_open_windows[i]->renderer, 0xff, 0xff, 0xff, 0); - SDL_RenderClear(_sgsdl2_open_windows[i]->renderer); - _sgsdl2_restore_default_render_target(i, data); - } + SDL_SetTextureBlendMode(data->texture[i], SDL_BLENDMODE_BLEND); - //data->surface = SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0xff0000, 0xff00, 0xff); - data->surface = SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0xff0000, 0xff00, 0xff); - _sgsdl2_clear_sdl_surface(data->surface,{0xff, 0xff, 0xff, 0xff}); + _sgsdl2_set_renderer_target(i, data); + SDL_SetRenderDrawColor(_sgsdl2_open_windows[i]->renderer, 0xff, 0xff, 0xff, 0); + SDL_RenderClear(_sgsdl2_open_windows[i]->renderer); + _sgsdl2_restore_default_render_target(i, data); + } + } + else + { + data->texture = nullptr; + } _sgsdl2_add_bitmap(data); return result; @@ -2017,33 +1920,13 @@ sg_drawing_surface sgsdl2_load_bitmap(const char * filename) return result; } - sg_bitmap_be *data = static_cast(malloc(sizeof(sg_bitmap_be))); - - result._data = data; - - // Allocate space for one texture per window - if (_sgsdl2_num_open_windows > 0) - data->texture = static_cast(malloc(sizeof(SDL_Texture*) * _sgsdl2_num_open_windows)); - else - data->texture = NULL; - - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) - { - // Create a texture for each window - data->texture[i] = SDL_CreateTextureFromSurface(_sgsdl2_open_windows[i]->renderer, surface); - } + result = sgsdl2_create_bitmap(surface->w, surface->h); - data->surface = surface; - data->drawable = false; - data->clipped = false; - data->clip = {0,0,0,0}; - data->last_draw_loc = SG_BITMAP_NONE; + sg_bitmap_be *bitmap = static_cast(result._data); - result.kind = SGDS_Bitmap; - result.width = surface->w; - result.height = surface->h; + SDL_BlitSurface(surface, NULL, bitmap->surface, NULL); - _sgsdl2_add_bitmap(data); + bitmap->last_draw_loc = SG_BITMAP_SURFACE; return result; } @@ -2104,6 +1987,14 @@ void sgsdl2_draw_bitmap( sg_drawing_surface * src, sg_drawing_surface * dst, flo unsigned int count = _sgsdl2_renderer_count(dst); + //TODO: All we're doing here is making sure they're both in GPU memory. A better way to handle + // things would be to check if src & dst are both bitmaps and if their last draw op was + // done to their surfaces (rather than textures). If that's the case, we can simply blit + // their surfaces together. + _sgsdl2_surface_to_texture(src); + _sgsdl2_surface_to_texture(dst); + static_cast(dst->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(dst, i); diff --git a/Backend/Test/src/main.cpp b/Backend/Test/src/main.cpp index c92f2828..34fff043 100644 --- a/Backend/Test/src/main.cpp +++ b/Backend/Test/src/main.cpp @@ -426,9 +426,8 @@ void test_direct_pixel_speed(sg_drawing_surface *window_arr, int sz) for (int w = 0; w < sz; w++) { float data[] = {0,0}; - int start_time = _sg_functions->utils.get_ticks(); - for (int y = 0; y < 600; y++) + for (int y = 0; y < (120 * cnt); y++) { for (int x = 0; x < 800; x++) { @@ -444,7 +443,7 @@ void test_direct_pixel_speed(sg_drawing_surface *window_arr, int sz) refresh_or_draw(&window_arr[w]); cout << " Direct pixel drawing time for window " << w - << " was " << end_time - start_time << "ms" << endl; + << " with area of 800x" << cnt * 120 << " was " << end_time - start_time << "ms" << endl; } } cout << endl; @@ -472,7 +471,7 @@ void test_bitmap_pixel_speed(sg_drawing_surface *window_arr, int sz) _sg_functions->graphics.clear_drawing_surface( &bitmap, {1,1,1,1} ); - for (int y = 0; y < 600; y++) + for (int y = 0; y < (120 * cnt); y++) { for (int x = 0; x < 800; x++) { @@ -974,6 +973,11 @@ bool test_basic_drawing(int drawing_test_run) cout << "Testing Basic Drawing!" << endl; cout << drawing_test_run << endl; + if (!drawing_test_run) + { + drawing_test_run = -1; + } + sg_drawing_surface window; window = _sg_functions->graphics.open_window("Test Basic Drawing", 800, 600); From b17d6fe295ce8b1a422625bafb44c60beff00732 Mon Sep 17 00:00:00 2001 From: Aloz1 Date: Thu, 4 Aug 2016 10:50:51 +1000 Subject: [PATCH 4/6] Removed check to see if bitmaps have surface. All bitmaps should have a surface, otherwise there will be serious issues when trying to draw to the surface, or sync the surface to it's corresponding texture. Thus this function has been made redundant and has been optimised out. --- Backend/SGSDL2/src/SGSDL2Graphics.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.cpp b/Backend/SGSDL2/src/SGSDL2Graphics.cpp index 06d27315..cd3ab969 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.cpp +++ b/Backend/SGSDL2/src/SGSDL2Graphics.cpp @@ -289,16 +289,6 @@ void _sgsdl2_add_window(sg_window_be * window) } } -bool _sgsdl2_has_open_bitmap_without_surface() -{ - for (uint i = 0; i < _sgsdl2_num_open_bitmaps; i++) - { - if ( ! _sgsdl2_open_bitmaps[i]->surface ) return true; - } - - return false; -} - void _sgsdl2_get_pixels_from_renderer(SDL_Renderer *renderer, int x, int y, int w, int h, int *pixels) { SDL_Rect rect = {x, y, w, h}; @@ -387,7 +377,7 @@ void _sgsdl2_remove_window(sg_window_be * window_be) exit(-1); } - if ( _sgsdl2_num_open_windows == 1 && _sgsdl2_has_open_bitmap_without_surface() ) + if ( _sgsdl2_num_open_windows == 1 ) { // Need to keep a window open to retain the bitmap surface _sgsdl2_bitmaps_to_surface(); From 03cf704835bf957e3340b5d177d5996acf5e485f Mon Sep 17 00:00:00 2001 From: Aloz1 Date: Thu, 4 Aug 2016 15:31:02 +1000 Subject: [PATCH 5/6] Fix memory leak in load_bitmap The image is opened through a read only surface, then copied to a newly created bitmap. This properly frees image surface after copying it to the bitmap. --- Backend/SGSDL2/src/SGSDL2Graphics.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.cpp b/Backend/SGSDL2/src/SGSDL2Graphics.cpp index cd3ab969..9027fb8c 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.cpp +++ b/Backend/SGSDL2/src/SGSDL2Graphics.cpp @@ -1918,6 +1918,8 @@ sg_drawing_surface sgsdl2_load_bitmap(const char * filename) bitmap->last_draw_loc = SG_BITMAP_SURFACE; + SDL_FreeSurface(surface); + return result; } From 5413ec7a0dfdd7eccf605a402eabbffe6a0e364c Mon Sep 17 00:00:00 2001 From: Aloz1 Date: Thu, 4 Aug 2016 15:36:26 +1000 Subject: [PATCH 6/6] Removed bitmap drawable flag. Bitmaps no longer need to know if they're drawable as their SDL_Surface is always drawable and always exists. --- Backend/SGSDL2/src/SGSDL2Graphics.cpp | 1 - Backend/SGSDL2/src/SGSDL2Graphics.h | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.cpp b/Backend/SGSDL2/src/SGSDL2Graphics.cpp index 9027fb8c..8bf2e144 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.cpp +++ b/Backend/SGSDL2/src/SGSDL2Graphics.cpp @@ -1865,7 +1865,6 @@ sg_drawing_surface sgsdl2_create_bitmap(int width, int height) data->clipped = false; data->clip = {0, 0, width, height}; - data->drawable = true; data->last_draw_loc = SG_BITMAP_NONE; data->surface = SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0xff0000, 0xff00, 0xff); diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.h b/Backend/SGSDL2/src/SGSDL2Graphics.h index db96f0b2..e9821383 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.h +++ b/Backend/SGSDL2/src/SGSDL2Graphics.h @@ -42,7 +42,7 @@ typedef struct sg_window_be bool clipped; SDL_Rect clip; unsigned int idx; - + // Event data store sg_window_data event_data; sg_drawing_surface *surface; @@ -56,8 +56,6 @@ typedef struct sg_bitmap_be sg_bitmap_draw_loc last_draw_loc; bool clipped; SDL_Rect clip; - - bool drawable; // can be drawn on } sg_bitmap_be;