1/************************************************************************** 2 * 3 * Copyright 2009 Artur Wyszynski <harakash@gmail.com> 4 * Copyright 2013-2014 Alexander von Gluck IV <kallisti5@unixzen.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 **************************************************************************/ 27 28#include <stdio.h> 29 30#include "pipe/p_compiler.h" 31#include "pipe/p_defines.h" 32#include "pipe/p_format.h" 33#include "util/u_inlines.h" 34#include "util/format/u_format.h" 35#include "util/u_math.h" 36#include "util/u_memory.h" 37#include "frontend/api.h" 38#include "frontend/sw_winsys.h" 39 40#include "hgl_sw_winsys.h" 41 42#include <Bitmap.h> 43#include <OS.h> 44 45#ifdef DEBUG 46# define TRACE(x...) printf("hgl:winsys: " x) 47# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__) 48#else 49# define TRACE(x...) 50# define CALLED() 51#endif 52#define ERROR(x...) printf("hgl:winsys: " x) 53 54 55struct haiku_displaytarget 56{ 57 enum pipe_format format; 58 color_space colorSpace; 59 60 unsigned width; 61 unsigned height; 62 unsigned stride; 63 64 unsigned size; 65 66 void* data; 67 BBitmap* bitmap; 68}; 69 70 71// Cast 72static inline struct haiku_displaytarget* 73hgl_sw_displaytarget(struct sw_displaytarget* target) 74{ 75 return (struct haiku_displaytarget *)target; 76} 77 78 79static void 80hgl_winsys_destroy(struct sw_winsys* winsys) 81{ 82 FREE(winsys); 83} 84 85 86static bool 87hgl_winsys_is_displaytarget_format_supported(struct sw_winsys* winsys, 88 unsigned textureUsage, enum pipe_format format) 89{ 90 // TODO STUB 91 return true; 92} 93 94static color_space 95hgl_winsys_convert_cs(enum pipe_format format) 96{ 97 // TODO: B_RGB24, B_RGB16, B_RGB15? 98 switch(format) { 99 case PIPE_FORMAT_B5G6R5_UNORM: 100 return B_CMAP8; 101 case PIPE_FORMAT_A8B8G8R8_UNORM: 102 case PIPE_FORMAT_X8B8G8R8_UNORM: 103 default: 104 return B_RGB32; 105 } 106} 107 108static struct sw_displaytarget* 109hgl_winsys_displaytarget_create(struct sw_winsys* winsys, 110 unsigned textureUsage, enum pipe_format format, unsigned width, 111 unsigned height, unsigned alignment, const void *front_private, 112 unsigned* stride) 113{ 114 struct haiku_displaytarget* haikuDisplayTarget 115 = CALLOC_STRUCT(haiku_displaytarget); 116 assert(haikuDisplayTarget); 117 118 TRACE("%s: %d x %d\n", __func__, width, height); 119 120 haikuDisplayTarget->colorSpace = hgl_winsys_convert_cs(format); 121 haikuDisplayTarget->format = format; 122 haikuDisplayTarget->width = width; 123 haikuDisplayTarget->height = height; 124 125 size_t formatStride = util_format_get_stride(format, width); 126 unsigned blockSize = util_format_get_nblocksy(format, height); 127 128 haikuDisplayTarget->stride = align(formatStride, alignment); 129 haikuDisplayTarget->size = haikuDisplayTarget->stride * blockSize; 130 131 if (textureUsage & PIPE_BIND_DISPLAY_TARGET) { 132 haikuDisplayTarget->data = NULL; 133 haikuDisplayTarget->bitmap = new BBitmap( 134 BRect(0, 0, width - 1, height - 1), 135 haikuDisplayTarget->colorSpace, 136 haikuDisplayTarget->stride); 137 } else { 138 haikuDisplayTarget->data 139 = align_malloc(haikuDisplayTarget->size, alignment); 140 141 haikuDisplayTarget->bitmap = NULL; 142 } 143 144 *stride = haikuDisplayTarget->stride; 145 146 // Cast to ghost sw_displaytarget type 147 return (struct sw_displaytarget*)haikuDisplayTarget; 148} 149 150 151static void 152hgl_winsys_displaytarget_destroy(struct sw_winsys* winsys, 153 struct sw_displaytarget* displayTarget) 154{ 155 struct haiku_displaytarget* haikuDisplayTarget 156 = hgl_sw_displaytarget(displayTarget); 157 158 if (!haikuDisplayTarget) 159 return; 160 161 if (haikuDisplayTarget->data != NULL) 162 align_free(haikuDisplayTarget->data); 163 164 if (haikuDisplayTarget->bitmap != NULL) 165 delete haikuDisplayTarget->bitmap; 166 167 FREE(haikuDisplayTarget); 168} 169 170 171static struct sw_displaytarget* 172hgl_winsys_displaytarget_from_handle(struct sw_winsys* winsys, 173 const struct pipe_resource* templat, struct winsys_handle* whandle, 174 unsigned* stride) 175{ 176 return NULL; 177} 178 179 180static bool 181hgl_winsys_displaytarget_get_handle(struct sw_winsys* winsys, 182 struct sw_displaytarget* displayTarget, struct winsys_handle* whandle) 183{ 184 return false; 185} 186 187 188static void* 189hgl_winsys_displaytarget_map(struct sw_winsys* winsys, 190 struct sw_displaytarget* displayTarget, unsigned flags) 191{ 192 struct haiku_displaytarget* haikuDisplayTarget 193 = hgl_sw_displaytarget(displayTarget); 194 195 if (haikuDisplayTarget->bitmap != NULL) 196 return haikuDisplayTarget->bitmap->Bits(); 197 198 return haikuDisplayTarget->data; 199} 200 201 202static void 203hgl_winsys_displaytarget_unmap(struct sw_winsys* winsys, 204 struct sw_displaytarget* displayTarget) 205{ 206 return; 207} 208 209 210static void 211hgl_winsys_displaytarget_display(struct sw_winsys* winsys, 212 struct sw_displaytarget* displayTarget, void* contextPrivate, 213 struct pipe_box *box) 214{ 215 assert(contextPrivate); 216 217 struct haiku_displaytarget* haikuDisplayTarget 218 = hgl_sw_displaytarget(displayTarget); 219 220 HGLWinsysContext *context = (HGLWinsysContext*)contextPrivate; 221 context->Display(haikuDisplayTarget->bitmap, NULL); 222} 223 224 225struct sw_winsys* 226hgl_create_sw_winsys() 227{ 228 struct sw_winsys* winsys = CALLOC_STRUCT(sw_winsys); 229 230 if (!winsys) 231 return NULL; 232 233 // Attach winsys hooks for Haiku 234 winsys->destroy = hgl_winsys_destroy; 235 winsys->is_displaytarget_format_supported 236 = hgl_winsys_is_displaytarget_format_supported; 237 winsys->displaytarget_create = hgl_winsys_displaytarget_create; 238 winsys->displaytarget_from_handle = hgl_winsys_displaytarget_from_handle; 239 winsys->displaytarget_get_handle = hgl_winsys_displaytarget_get_handle; 240 winsys->displaytarget_map = hgl_winsys_displaytarget_map; 241 winsys->displaytarget_unmap = hgl_winsys_displaytarget_unmap; 242 winsys->displaytarget_display = hgl_winsys_displaytarget_display; 243 winsys->displaytarget_destroy = hgl_winsys_displaytarget_destroy; 244 245 return winsys; 246} 247