21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED 27 #include "../SDL_sysrender.h" 33 #define RENDERER_CONTEXT_MAJOR 1 34 #define RENDERER_CONTEXT_MINOR 1 36 #if defined(SDL_VIDEO_DRIVER_PANDORA) 53 static const float inv255f = 1.0f / 255.0f;
55 typedef struct GLES_FBOList GLES_FBOList;
80 } GLES_DrawStateCache;
86 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 87 #define SDL_PROC_OES SDL_PROC 91 SDL_bool GL_OES_framebuffer_object_supported;
95 SDL_bool GL_OES_blend_func_separate_supported;
96 SDL_bool GL_OES_blend_equation_separate_supported;
97 SDL_bool GL_OES_blend_subtract_supported;
99 GLES_DrawStateCache drawstate;
122 error =
"GL_NO_ERROR";
125 error =
"GL_INVALID_ENUM";
128 error =
"GL_INVALID_VALUE";
131 error =
"GL_INVALID_OPERATION";
134 error =
"GL_STACK_OVERFLOW";
137 error =
"GL_STACK_UNDERFLOW";
140 error =
"GL_OUT_OF_MEMORY";
149 static int GLES_LoadFunctions(GLES_RenderData *
data)
151 #if SDL_VIDEO_DRIVER_UIKIT 152 #define __SDL_NOGETPROCADDR__ 153 #elif SDL_VIDEO_DRIVER_ANDROID 154 #define __SDL_NOGETPROCADDR__ 155 #elif SDL_VIDEO_DRIVER_PANDORA 156 #define __SDL_NOGETPROCADDR__ 159 #ifdef __SDL_NOGETPROCADDR__ 160 #define SDL_PROC(ret,func,params) data->func=func; 161 #define SDL_PROC_OES(ret,func,params) data->func=func; 163 #define SDL_PROC(ret,func,params) \ 165 data->func = SDL_GL_GetProcAddress(#func); \ 166 if ( ! data->func ) { \ 167 return SDL_SetError("Couldn't load GLES function %s: %s", #func, SDL_GetError()); \ 170 #define SDL_PROC_OES(ret,func,params) \ 172 data->func = SDL_GL_GetProcAddress(#func); \ 182 static GLES_FBOList *
185 GLES_FBOList *result = data->framebuffers;
186 while ((result) && ((result->w != w) || (result->h != h)) ) {
187 result = result->next;
189 if (result ==
NULL) {
193 data->glGenFramebuffersOES(1, &result->FBO);
194 result->next = data->framebuffers;
195 data->framebuffers =
result;
204 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
218 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
227 GLES_GetOutputSize(
SDL_Renderer * renderer,
int *w,
int *h)
265 return GL_FUNC_ADD_OES;
267 return GL_FUNC_SUBTRACT_OES;
269 return GL_FUNC_REVERSE_SUBTRACT_OES;
278 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
294 if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->GL_OES_blend_func_separate_supported) {
297 if (colorOperation != alphaOperation && !data->GL_OES_blend_equation_separate_supported) {
307 power_of_2(
int input)
311 while (value < input) {
320 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->
driverdata;
321 GLES_TextureData *data;
324 int texture_w, texture_h;
328 GLES_ActivateRenderer(renderer);
330 switch (texture->
format) {
340 data = (GLES_TextureData *)
SDL_calloc(1,
sizeof(*data));
347 data->pixels =
SDL_calloc(1, texture->
h * data->pitch);
356 if (!renderdata->GL_OES_framebuffer_object_supported) {
358 return SDL_SetError(
"GL_OES_framebuffer_object not supported");
360 data->fbo = GLES_GetFBO(renderer->
driverdata, texture->
w, texture->
h);
366 renderdata->glGetError();
368 renderdata->glGenTextures(1, &data->texture);
369 result = renderdata->glGetError();
372 return GLES_SetError(
"glGenTextures()", result);
377 texture_w = power_of_2(texture->
w);
378 texture_h = power_of_2(texture->
h);
379 data->texw = (
GLfloat) texture->
w / texture_w;
380 data->texh = (
GLfloat) texture->
h / texture_h;
383 data->formattype =
type;
385 renderdata->glBindTexture(data->type, data->texture);
391 renderdata->glTexImage2D(data->type, 0,
internalFormat, texture_w,
394 renderdata->drawstate.texture =
texture;
395 renderdata->drawstate.texturing =
SDL_FALSE;
397 result = renderdata->glGetError();
400 return GLES_SetError(
"glTexImage2D()", result);
411 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->
driverdata;
412 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
418 GLES_ActivateRenderer(renderer);
421 if (rect->
w <= 0 || rect->
h <= 0) {
427 src = (
Uint8 *)pixels;
428 if (pitch != srcPitch) {
434 for (y = 0; y < rect->
h; ++
y) {
437 pixels = (
Uint8 *)pixels + pitch;
443 renderdata->glGetError();
444 renderdata->glEnable(data->type);
445 renderdata->glBindTexture(data->type, data->texture);
447 renderdata->glTexSubImage2D(data->type,
456 renderdata->glDisable(data->type);
459 renderdata->drawstate.texture =
texture;
460 renderdata->drawstate.texturing =
SDL_FALSE;
470 const SDL_Rect * rect,
void **pixels,
int *pitch)
472 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
475 (
void *) ((
Uint8 *) data->pixels + rect->
y * data->pitch +
477 *pitch = data->pitch;
484 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
492 GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
498 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
499 GLES_TextureData *texturedata =
NULL;
502 if (!data->GL_OES_framebuffer_object_supported) {
503 return SDL_SetError(
"Can't enable render target support in this renderer");
506 data->drawstate.viewport_dirty =
SDL_TRUE;
508 if (texture ==
NULL) {
509 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer);
513 texturedata = (GLES_TextureData *) texture->
driverdata;
514 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
516 data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
518 status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
519 if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
520 return SDL_SetError(
"glFramebufferTexture2DOES() failed");
543 for (i = 0; i <
count; i++) {
544 *(verts++) = 0.5
f + points[i].
x;
545 *(verts++) = 0.5
f + points[i].y;
563 for (i = 0; i <
count; i++) {
586 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
587 GLfloat minx, miny, maxx, maxy;
588 GLfloat minu, maxu, minv, maxv;
599 maxx = dstrect->
x + dstrect->
w;
600 maxy = dstrect->
y + dstrect->
h;
602 minu = (
GLfloat) srcrect->
x / texture->
w;
603 minu *= texturedata->texw;
604 maxu = (
GLfloat) (srcrect->
x + srcrect->
w) / texture->
w;
605 maxu *= texturedata->texw;
606 minv = (
GLfloat) srcrect->
y / texture->
h;
607 minv *= texturedata->texh;
608 maxv = (
GLfloat) (srcrect->
y + srcrect->
h) / texture->
h;
609 maxv *= texturedata->texh;
637 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
638 GLfloat minx, miny, maxx, maxy;
640 GLfloat minu, maxu, minv, maxv;
651 minx = dstrect->
w - centerx;
656 maxx = dstrect->
w - centerx;
660 miny = dstrect->
h - centery;
665 maxy = dstrect->
h - centery;
668 minu = (
GLfloat) srcquad->
x / texture->
w;
669 minu *= texturedata->texw;
670 maxu = (
GLfloat) (srcquad->
x + srcquad->
w) / texture->
w;
671 maxu *= texturedata->texw;
672 minv = (
GLfloat) srcquad->
y / texture->
h;
673 minv *= texturedata->texh;
674 maxv = (
GLfloat) (srcquad->
y + srcquad->
h) / texture->
h;
675 maxv *= texturedata->texh;
697 *(verts++) = (
GLfloat) dstrect->
x + centerx;
698 *(verts++) = (
GLfloat) dstrect->
y + centery;
712 const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
714 if (color != data->drawstate.color) {
719 data->glColor4f(fr, fg, fb, fa);
720 data->drawstate.color =
color;
723 if (data->drawstate.viewport_dirty) {
725 const SDL_bool istarget = (data->drawstate.target !=
NULL);
727 data->glLoadIdentity();
728 data->glViewport(viewport->
x,
729 istarget ? viewport->
y : (data->drawstate.drawableh - viewport->
y - viewport->
h),
730 viewport->
w, viewport->
h);
731 if (viewport->
w && viewport->
h) {
733 (
GLfloat) (istarget ? 0 : viewport->
h),
734 (
GLfloat) (istarget ? viewport->
h : 0),
738 data->drawstate.viewport_dirty =
SDL_FALSE;
741 if (data->drawstate.cliprect_enabled_dirty) {
742 if (data->drawstate.cliprect_enabled) {
747 data->drawstate.cliprect_enabled_dirty =
SDL_FALSE;
750 if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
751 const SDL_Rect *viewport = &data->drawstate.viewport;
752 const SDL_Rect *rect = &data->drawstate.cliprect;
753 const SDL_bool istarget = (data->drawstate.target !=
NULL);
754 data->glScissor(viewport->
x + rect->
x,
755 istarget ? viewport->
y + rect->
y : data->drawstate.drawableh - viewport->
y - rect->
y - rect->
h,
757 data->drawstate.cliprect_dirty =
SDL_FALSE;
760 if (blend != data->drawstate.blend) {
765 if (data->GL_OES_blend_func_separate_supported) {
774 if (data->GL_OES_blend_equation_separate_supported) {
777 }
else if (data->GL_OES_blend_subtract_supported) {
781 data->drawstate.blend = blend;
784 if ((cmd->
data.
draw.texture !=
NULL) != data->drawstate.texturing) {
792 data->drawstate.texturing =
SDL_TRUE;
803 if (texture != data->drawstate.texture) {
804 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
806 data->drawstate.texture =
texture;
813 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
816 if (GLES_ActivateRenderer(renderer) < 0) {
820 data->drawstate.target = renderer->
target;
833 SDL_Rect *viewport = &data->drawstate.viewport;
836 data->drawstate.viewport_dirty =
SDL_TRUE;
843 if (data->drawstate.cliprect_enabled != cmd->
data.
cliprect.enabled) {
844 data->drawstate.cliprect_enabled = cmd->
data.
cliprect.enabled;
845 data->drawstate.cliprect_enabled_dirty =
SDL_TRUE;
849 data->drawstate.cliprect_dirty =
SDL_TRUE;
859 const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
860 if (color != data->drawstate.clear_color) {
865 data->glClearColor(fr, fg, fb, fa);
866 data->drawstate.clear_color =
color;
869 if (data->drawstate.cliprect_enabled) {
871 data->drawstate.cliprect_enabled_dirty =
SDL_TRUE;
880 const size_t count = cmd->
data.
draw.count;
883 data->glVertexPointer(2,
GL_FLOAT, 0, verts);
890 const size_t count = cmd->
data.
draw.count;
892 data->glVertexPointer(2,
GL_FLOAT, 0, verts);
893 if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) {
905 const size_t count = cmd->
data.
draw.count;
909 data->glVertexPointer(2,
GL_FLOAT, 0, verts);
910 for (i = 0; i <
count; ++
i, offset += 4) {
918 SetCopyState(data, cmd);
919 data->glVertexPointer(2,
GL_FLOAT, 0, verts);
920 data->glTexCoordPointer(2,
GL_FLOAT, 0, verts + 8);
927 const GLfloat translatex = verts[16];
928 const GLfloat translatey = verts[17];
929 const GLfloat angle = verts[18];
930 SetCopyState(data, cmd);
931 data->glVertexPointer(2,
GL_FLOAT, 0, verts);
932 data->glTexCoordPointer(2,
GL_FLOAT, 0, verts + 8);
935 data->glPushMatrix();
936 data->glTranslatef(translatex, translatey, 0.0
f);
937 data->glRotatef(angle, 0.0, 0.0, 1.0);
955 Uint32 pixel_format,
void * pixels,
int pitch)
957 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
965 GLES_ActivateRenderer(renderer);
977 data->glReadPixels(rect->
x, renderer->
target ? rect->
y : (h-rect->
y)-rect->
h,
984 src = (
Uint8*)temp_pixels + (rect->
h-1)*temp_pitch;
999 temp_format, temp_pixels, temp_pitch,
1000 pixel_format, pixels, pitch);
1009 GLES_ActivateRenderer(renderer);
1017 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->
driverdata;
1019 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
1021 GLES_ActivateRenderer(renderer);
1023 if (renderdata->drawstate.texture == texture) {
1024 renderdata->drawstate.texture =
NULL;
1026 if (renderdata->drawstate.target == texture) {
1027 renderdata->drawstate.target =
NULL;
1033 if (data->texture) {
1034 renderdata->glDeleteTextures(1, &data->texture);
1044 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1047 if (data->context) {
1048 while (data->framebuffers) {
1049 GLES_FBOList *nextnode = data->framebuffers->next;
1050 data->glDeleteFramebuffersOES(1, &data->framebuffers->FBO);
1052 data->framebuffers = nextnode;
1063 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1064 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
1065 GLES_ActivateRenderer(renderer);
1068 data->glBindTexture(texturedata->type, texturedata->texture);
1070 data->drawstate.texture =
texture;
1071 data->drawstate.texturing =
SDL_TRUE;
1074 *texw = (float)texturedata->texw;
1077 *texh = (float)texturedata->texh;
1085 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1086 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
1087 GLES_ActivateRenderer(renderer);
1088 data->glDisable(texturedata->type);
1090 data->drawstate.texture =
NULL;
1100 GLES_RenderData *
data;
1103 int profile_mask = 0, major = 0, minor = 0;
1130 data = (GLES_RenderData *)
SDL_calloc(1,
sizeof(*data));
1132 GLES_DestroyRenderer(renderer);
1165 if (!data->context) {
1166 GLES_DestroyRenderer(renderer);
1170 GLES_DestroyRenderer(renderer);
1174 if (GLES_LoadFunctions(data) < 0) {
1175 GLES_DestroyRenderer(renderer);
1197 data->GL_OES_framebuffer_object_supported =
SDL_TRUE;
1201 data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value);
1202 data->window_framebuffer = (
GLuint)value;
1204 data->framebuffers =
NULL;
1207 data->GL_OES_blend_func_separate_supported =
SDL_TRUE;
1210 data->GL_OES_blend_equation_separate_supported =
SDL_TRUE;
1213 data->GL_OES_blend_subtract_supported =
SDL_TRUE;
1221 data->glLoadIdentity();
1226 data->glClearColor(1.0
f, 1.0
f, 1.0
f, 1.0
f);
1229 data->drawstate.color = 0xFFFFFFFF;
1230 data->drawstate.clear_color = 0xFFFFFFFF;
1235 if (changed_window) {
1246 GLES_CreateRenderer,
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
SDL_BlendFactor
The normalized factor used to multiply pixel components.
#define GL_STACK_UNDERFLOW
#define SDL_GL_ExtensionSupported
GLdouble GLdouble GLdouble r
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
struct SDL_RenderCommand::@30::@31 viewport
#define GL_INVALID_OPERATION
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
#define SDL_GL_CreateContext
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
const GLuint * framebuffers
GLint GLint GLint GLint GLint x
struct SDL_RenderCommand::@30::@32 cliprect
SDL_RenderDriver GLES_RenderDriver
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
GLuint GLuint GLsizei count
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
struct SDL_RenderCommand::@30::@34 color
GLfloat GLfloat GLfloat GLfloat h
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
static screen_context_t context
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
#define SDL_GetWindowFlags
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
#define SDL_BYTESPERPIXEL(X)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define GL_TEXTURE_MAG_FILTER
#define GL_TRIANGLE_STRIP
#define GL_ONE_MINUS_SRC_ALPHA
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
#define GL_ONE_MINUS_SRC_COLOR
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLint GLint GLsizei width
GLfixed GLfixed GLint GLint GLfixed points
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
#define GL_PACK_ALIGNMENT
#define GL_MAX_TEXTURE_SIZE
static SDL_BlendMode blendMode
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
#define SDL_small_alloc(type, count, pisstack)
#define SDL_GL_SetAttribute
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
#define SDL_GL_GetDrawableSize
#define GL_ONE_MINUS_DST_ALPHA
GLenum GLenum GLuint texture
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define SDL_GL_GetSwapInterval
GLenum GLenum GLenum input
struct SDL_RenderCommand::@30::@33 draw
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
#define GL_STACK_OVERFLOW
static SDL_Renderer * renderer
#define SDL_GL_SetSwapInterval
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
#define GL_TEXTURE_WRAP_T
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
GLint GLint GLint GLint GLint GLint y
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
#define GL_COLOR_BUFFER_BIT
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Window state change event data (event.window.*)
#define SDL_OutOfMemory()
#define SDL_GL_GetCurrentContext
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
GLint GLint GLsizei GLsizei height
#define SDL_GL_MakeCurrent
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
EGLSurface EGLNativeWindowType * window
#define SDL_GetRendererOutputSize
SDL_RenderCommandType command
The type used to identify a window.
union SDL_RenderCommand::@30 data
#define GL_ONE_MINUS_DST_COLOR
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
#define SDL_small_free(ptr, isstack)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
GLuint GLuint GLsizei GLenum type
#define GL_TEXTURE_COORD_ARRAY
#define SDL_GL_GetAttribute
#define SDL_ConvertPixels
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
#define SDL_GL_DeleteContext
EGLSurface EGLint * rects
#define GL_TEXTURE_WRAP_S
GLuint GLsizei GLsizei * length
#define GL_TEXTURE_MIN_FILTER
struct SDL_RenderCommand * next
GLboolean GLboolean GLboolean GLboolean a
#define GL_UNPACK_ALIGNMENT
GLboolean GLboolean GLboolean b
#define SDL_GL_SwapWindow
A rectangle, with the origin at the upper left (floating point).
The structure that defines a point (floating point)
A rectangle, with the origin at the upper left (integer).