Exemplo n.º 1
0
static void wgl_destroy_display(ALLEGRO_DISPLAY *disp)
{
   ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver();
   ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)disp;
   ALLEGRO_DISPLAY *old_disp = al_get_current_display();

   if (old_disp != disp)
      _al_set_current_display_only(disp);

   if (system->mouse_grab_display == disp)
      system->mouse_grab_display = NULL;

   destroy_display_internals(wgl_disp);
   _al_event_source_free(&disp->es);
   _al_vector_find_and_delete(&system->system.displays, &disp);

   _al_vector_free(&disp->bitmaps);
   al_free(disp->ogl_extras);

   if (old_disp != disp)
      _al_set_current_display_only(old_disp);

   al_free(disp->vertex_cache);
   al_free(wgl_disp);
}
Exemplo n.º 2
0
/* Function: al_destroy_display
 */
void al_destroy_display(ALLEGRO_DISPLAY *display)
{
   if (display) {
      /* This causes warnings and potential errors on Android because
       * it clears the context and Android needs this thread to have
       * the context bound in its destroy function and to destroy the
       * shader. Just skip this part on Android.
       */
#ifndef ALLEGRO_ANDROID
      ALLEGRO_BITMAP *bmp;

      bmp = al_get_target_bitmap();
      if (bmp && _al_get_bitmap_display(bmp) == display)
         al_set_target_bitmap(NULL);

      /* This can happen if we have a current display, but the target bitmap
       * was a memory bitmap.
       */
      if (display == al_get_current_display())
         _al_set_current_display_only(NULL);
#endif

      al_destroy_shader(display->default_shader);
      display->default_shader = NULL;

      ASSERT(display->vt);
      display->vt->destroy_display(display);
   }
}
Exemplo n.º 3
0
/* Function: al_restore_state
 */
void al_restore_state(ALLEGRO_STATE const *state)
{
   thread_local_state *tls;
   INTERNAL_STATE *stored;
   int flags;

   if ((tls = tls_get()) == NULL)
      return;
   
   stored = (void *)state;
   flags = stored->flags;

   if (flags & ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) {
      _STORE(new_display_flags);
      _STORE(new_display_refresh_rate);
      _STORE(new_display_adapter);
      _STORE(new_window_x);
      _STORE(new_window_y);
      _STORE(new_display_settings);
   }
   
   if (flags & ALLEGRO_STATE_NEW_BITMAP_PARAMETERS) {
      _STORE(new_bitmap_format);
      _STORE(new_bitmap_flags);
   }
   
   if (flags & ALLEGRO_STATE_DISPLAY) {
      _STORE(current_display);
      _al_set_current_display_only(tls->current_display);
   }

   if (flags & ALLEGRO_STATE_TARGET_BITMAP) {
      _STORE(target_bitmap);
      al_set_target_bitmap(tls->target_bitmap);
   }
   
   if (flags & ALLEGRO_STATE_BLENDER) {
      tls->current_blender = stored->stored_blender;
   }

   if (flags & ALLEGRO_STATE_NEW_FILE_INTERFACE) {
      _STORE(new_file_interface);
      _STORE(fs_interface);
   }
   
   if (flags & ALLEGRO_STATE_TRANSFORM) {
      ALLEGRO_BITMAP *bitmap = al_get_target_bitmap();
      if (bitmap)
         al_use_transform(&stored->stored_transform);
   }
}
Exemplo n.º 4
0
/* Function: al_set_current_opengl_context
 */
void al_set_current_opengl_context(ALLEGRO_DISPLAY *display)
{
   ASSERT(display);

   if (!(display->flags & ALLEGRO_OPENGL))
      return;

   if (display) {
      ALLEGRO_BITMAP *bmp = al_get_target_bitmap();
      if (bmp && bmp->display && bmp->display != display) {
         al_set_target_bitmap(NULL);
      }
   }

   _al_set_current_display_only(display);
}
Exemplo n.º 5
0
static void raspberrypi_destroy_display(ALLEGRO_DISPLAY *d)
{
    ALLEGRO_DISPLAY_RASPBERRYPI *pidisplay = (ALLEGRO_DISPLAY_RASPBERRYPI *)d;

    hide_cursor(pidisplay);
    delete_cursor_data(pidisplay);

    _al_set_current_display_only(d);

    while (d->bitmaps._size > 0) {
        ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref_back(&d->bitmaps);
        ALLEGRO_BITMAP *b = *bptr;
        _al_convert_to_memory_bitmap(b);
    }

    _al_event_source_free(&d->es);

    ALLEGRO_SYSTEM_RASPBERRYPI *system = (void *)al_get_system_driver();
    _al_vector_find_and_delete(&system->system.displays, &d);

    eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglDestroySurface(egl_display, egl_window);
    eglDestroyContext(egl_display, egl_context);
    eglTerminate(egl_display);

    if (getenv("DISPLAY")) {
        _al_mutex_lock(&system->lock);
        XUnmapWindow(system->x11display, pidisplay->window);
        XDestroyWindow(system->x11display, pidisplay->window);
        _al_mutex_unlock(&system->lock);
    }

    if (system->mouse_grab_display == d) {
        system->mouse_grab_display = NULL;
    }
}
Exemplo n.º 6
0
ALLEGRO_LOCKED_REGION *_al_ogl_lock_region_new(ALLEGRO_BITMAP *bitmap,
   int x, int y, int w, int h, int format, int flags)
{
   ALLEGRO_BITMAP_EXTRA_OPENGL * const ogl_bitmap = bitmap->extra;
   const GLint gl_y = bitmap->h - y - h;
   ALLEGRO_DISPLAY *disp;
   ALLEGRO_DISPLAY *old_disp = NULL;
   ALLEGRO_BITMAP *old_target = al_get_target_bitmap();
   GLenum e;
   bool ok;
   bool restore_fbo = false;

   if (format == ALLEGRO_PIXEL_FORMAT_ANY) {
      /* Never pick compressed formats with ANY, as it interacts weirdly with
       * existing code (e.g. al_get_pixel_size() etc) */
      int bitmap_format = al_get_bitmap_format(bitmap);
      if (_al_pixel_format_is_compressed(bitmap_format)) {
         // XXX Get a good format from the driver?
         format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE;
      }
      else {
         format = bitmap_format;
      }
   }

   disp = al_get_current_display();
   format = _al_get_real_pixel_format(disp, format);

   /* Change OpenGL context if necessary. */
   if (!disp ||
      (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false &&
       _al_get_bitmap_display(bitmap) != disp))
   {
      old_disp = disp;
      _al_set_current_display_only(_al_get_bitmap_display(bitmap));
   }

   ok = true;

   /* Set up the pixel store state.  We will need to match it when unlocking.
    * There may be other pixel store state we should be setting.
    * See also pitfalls 7 & 8 from:
    * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/
    */
   glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
   {
      const int pixel_size = al_get_pixel_size(format);
      const int pixel_alignment = ogl_pixel_alignment(pixel_size);
      glPixelStorei(GL_PACK_ALIGNMENT, pixel_alignment);
      e = glGetError();
      if (e) {
         ALLEGRO_ERROR("glPixelStorei(GL_PACK_ALIGNMENT, %d) failed (%s).\n",
            pixel_alignment, _al_gl_error_string(e));
         ok = false;
      }
   }

   if (ok) {
      if (ogl_bitmap->is_backbuffer) {
         ALLEGRO_DEBUG("Locking backbuffer\n");
         ok = ogl_lock_region_backbuffer(bitmap, ogl_bitmap,
            x, gl_y, w, h, format, flags);
      }
      else if (flags & ALLEGRO_LOCK_WRITEONLY) {
         ALLEGRO_DEBUG("Locking non-backbuffer WRITEONLY\n");
         ok = ogl_lock_region_nonbb_writeonly(bitmap, ogl_bitmap,
            x, gl_y, w, h, format);
      }
      else {
         ALLEGRO_DEBUG("Locking non-backbuffer READWRITE\n");
         ok = ogl_lock_region_nonbb_readwrite(bitmap, ogl_bitmap,
            x, gl_y, w, h, format, &restore_fbo);
      }
   }

   glPopClientAttrib();

   /* Restore state after switching FBO. */
   if (restore_fbo) {
      if (!old_target) {
         /* Old target was NULL; release the context. */
         _al_set_current_display_only(NULL);
      }
      else if (!_al_get_bitmap_display(old_target)) {
         /* Old target was memory bitmap; leave the current display alone. */
      }
      else if (old_target != bitmap) {
         /* Old target was another OpenGL bitmap. */
         _al_ogl_setup_fbo(_al_get_bitmap_display(old_target), old_target);
      }
   }

   ASSERT(al_get_target_bitmap() == old_target);

   if (old_disp != NULL) {
      _al_set_current_display_only(old_disp);
   }

   if (ok) {
      return &bitmap->locked_region;
   }

   ALLEGRO_ERROR("Failed to lock region\n");
   ASSERT(ogl_bitmap->lock_buffer == NULL);
   return NULL;
}
Exemplo n.º 7
0
static void ogl_unlock_region_non_readonly(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap)
{
   const int lock_format = bitmap->locked_region.format;
   const int gl_y = bitmap->h - bitmap->lock_y - bitmap->lock_h;
   ALLEGRO_DISPLAY *old_disp = NULL;
   ALLEGRO_DISPLAY *disp;
   int orig_format;
   bool biased_alpha = false;
   GLenum e;

   disp = al_get_current_display();
   orig_format = _al_get_real_pixel_format(disp, _al_get_bitmap_memory_format(bitmap));

   /* Change OpenGL context if necessary. */
   if (!disp ||
      (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false &&
       _al_get_bitmap_display(bitmap) != disp))
   {
      old_disp = disp;
      _al_set_current_display_only(_al_get_bitmap_display(bitmap));
   }

   /* Keep this in sync with ogl_lock_region. */
   glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
   {
      const int lock_pixel_size = al_get_pixel_size(lock_format);
      const int pixel_alignment = ogl_pixel_alignment(lock_pixel_size);
      glPixelStorei(GL_UNPACK_ALIGNMENT, pixel_alignment);
      e = glGetError();
      if (e) {
         ALLEGRO_ERROR("glPixelStorei(GL_UNPACK_ALIGNMENT, %d) failed (%s).\n",
            pixel_alignment, _al_gl_error_string(e));
      }
   }
   if (exactly_15bpp(lock_format)) {
      /* OpenGL does not support 15-bpp internal format without an alpha,
       * so when storing such data we must ensure the alpha bit is set.
       */
      glPixelTransferi(GL_ALPHA_BIAS, 1);
      biased_alpha = true;
   }

   if (ogl_bitmap->is_backbuffer) {
      ALLEGRO_DEBUG("Unlocking backbuffer\n");
      ogl_unlock_region_backbuffer(bitmap, ogl_bitmap, gl_y);
   }
   else {
      glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture);
      if (ogl_bitmap->fbo_info) {
         ALLEGRO_DEBUG("Unlocking non-backbuffer (FBO)\n");
         ogl_unlock_region_nonbb_fbo(bitmap, ogl_bitmap, gl_y, orig_format);
      }
      else {
         ALLEGRO_DEBUG("Unlocking non-backbuffer (non-FBO)\n");
         ogl_unlock_region_nonbb_nonfbo(bitmap, ogl_bitmap, gl_y);
      }

      /* If using FBOs, we need to regenerate mipmaps explicitly now. */
      /* XXX why don't we check ogl_bitmap->fbo_info? */
      if ((al_get_bitmap_flags(bitmap) & ALLEGRO_MIPMAP) &&
         al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object)
      {
         glGenerateMipmapEXT(GL_TEXTURE_2D);
         e = glGetError();
         if (e) {
            ALLEGRO_ERROR("glGenerateMipmapEXT for texture %d failed (%s).\n",
               ogl_bitmap->texture, _al_gl_error_string(e));
         }
      }
   }

   if (biased_alpha) {
      glPixelTransferi(GL_ALPHA_BIAS, 0);
   }
   glPopClientAttrib();

   if (old_disp) {
      _al_set_current_display_only(old_disp);
   }
}
Exemplo n.º 8
0
ALLEGRO_LOCKED_REGION *_al_ogl_lock_region_new(ALLEGRO_BITMAP *bitmap,
   int x, int y, int w, int h, int format, int flags)
{
   ALLEGRO_BITMAP_EXTRA_OPENGL * const ogl_bitmap = bitmap->extra;
   const GLint gl_y = bitmap->h - y - h;
   ALLEGRO_DISPLAY *disp;
   ALLEGRO_DISPLAY *old_disp = NULL;
   GLenum e;

   if (format == ALLEGRO_PIXEL_FORMAT_ANY) {
      format = bitmap->format;
   }

   disp = al_get_current_display();
   format = _al_get_real_pixel_format(disp, format);

   /* Change OpenGL context if necessary. */
   if (!disp ||
      (bitmap->display->ogl_extras->is_shared == false &&
       bitmap->display != disp))
   {
      old_disp = disp;
      _al_set_current_display_only(bitmap->display);
   }

   /* Set up the pixel store state.  We will need to match it when unlocking.
    * There may be other pixel store state we should be setting.
    * See also pitfalls 7 & 8 from:
    * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/
    */
   glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
   {
      const int pixel_size = al_get_pixel_size(format);
      const int pixel_alignment = ogl_pixel_alignment(pixel_size);
      glPixelStorei(GL_PACK_ALIGNMENT, pixel_alignment);
      e = glGetError();
      if (e) {
         ALLEGRO_ERROR("glPixelStorei(GL_PACK_ALIGNMENT, %d) failed (%s).\n",
            pixel_alignment, _al_gl_error_string(e));
      }
   }

   if (ogl_bitmap->is_backbuffer) {
      ALLEGRO_DEBUG("Locking backbuffer\n");
      ogl_lock_region_backbuffer(bitmap, ogl_bitmap,
         x, gl_y, w, h, format, flags);
   }
   else if (flags & ALLEGRO_LOCK_WRITEONLY) {
      ALLEGRO_DEBUG("Locking non-backbuffer WRITEONLY\n");
      ogl_lock_region_nonbb_writeonly(bitmap, ogl_bitmap,
         x, gl_y, w, h, format);
   }
   else {
      ALLEGRO_DEBUG("Locking non-backbuffer READWRITE\n");
      ogl_lock_region_nonbb_readwrite(bitmap, ogl_bitmap,
         x, gl_y, w, h, format);
   }

   glPopClientAttrib();

   if (old_disp != NULL) {
      _al_set_current_display_only(old_disp);
   }

   return &bitmap->locked_region;
}
Exemplo n.º 9
0
/* Function: al_create_display
 */
ALLEGRO_DISPLAY *al_create_display(int w, int h)
{
   ALLEGRO_SYSTEM *system;
   ALLEGRO_DISPLAY_INTERFACE *driver;
   ALLEGRO_DISPLAY *display;
   ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings;
   int flags;

   system = al_get_system_driver();
   driver = system->vt->get_display_driver();
   if (!driver) {
      ALLEGRO_ERROR("Failed to create display (no display driver)\n");
      return NULL;
   }

   display = driver->create_display(w, h);
   if (!display) {
      ALLEGRO_ERROR("Failed to create display (NULL)\n");
      return NULL;
   }

   ASSERT(display->vt);

   settings = &display->extra_settings;
   flags = settings->required | settings->suggested;
   if (!(flags & (1 << ALLEGRO_AUTO_CONVERT_BITMAPS))) {
      settings->settings[ALLEGRO_AUTO_CONVERT_BITMAPS] = 1;
   }

   display->min_w = 0;
   display->min_h = 0;
   display->max_w = 0;
   display->max_h = 0;
   display->use_constraints = false;

   display->vertex_cache = 0;
   display->num_cache_vertices = 0;
   display->cache_enabled = false;
   display->vertex_cache_size = 0;
   display->cache_texture = 0;
   al_identity_transform(&display->projview_transform);

   display->default_shader = NULL;

   _al_vector_init(&display->display_invalidated_callbacks, sizeof(void *));
   _al_vector_init(&display->display_validated_callbacks, sizeof(void *));

   display->render_state.write_mask = ALLEGRO_MASK_RGBA | ALLEGRO_MASK_DEPTH;
   display->render_state.depth_test = false;
   display->render_state.depth_function = ALLEGRO_RENDER_LESS;
   display->render_state.alpha_test = false;
   display->render_state.alpha_function = ALLEGRO_RENDER_ALWAYS;
   display->render_state.alpha_test_value = 0;

   _al_vector_init(&display->bitmaps, sizeof(ALLEGRO_BITMAP*));

   if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) {
      al_set_target_bitmap(al_get_backbuffer(display));
   }
   else {
      ALLEGRO_DEBUG("ALLEGRO_COMPATIBLE_DISPLAY not set\n");
      _al_set_current_display_only(display);
   }

   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
      display->default_shader = _al_create_default_shader(display->flags);
      if (!display->default_shader) {
         al_destroy_display(display);
         return NULL;
      }
      al_use_shader(display->default_shader);
   }

   /* Clear the screen */
   if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) {
      al_clear_to_color(al_map_rgb(0, 0, 0));

      /* TODO:
       * on iphone, don't kill the initial splashscreen - in fact, it's also
       * annoying in linux to have an extra black frame as first frame and I
       * suppose we never really want it
       */
#if 0
      al_flip_display();
#endif
   }

   if (settings->settings[ALLEGRO_AUTO_CONVERT_BITMAPS]) {
      /* We convert video bitmaps to memory bitmaps when the display is
       * destroyed, so seems only fair to re-convertt hem when the
       * display is re-created again.
       */
      al_convert_memory_bitmaps();
   }

   return display;
}