Пример #1
0
EGLBoolean EGLAPIENTRY
eglWaitNative(EGLint engine)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   _EGLDisplay *disp;
   _EGLDriver *drv;
   EGLBoolean ret;

   if (!ctx)
      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);

   disp = ctx->Resource.Display;
   _eglLockMutex(&disp->Mutex);

   /* let bad current context imply bad current surface */
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
       _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);

   /* a valid current context implies an initialized current display */
   assert(disp->Initialized);
   drv = disp->Driver;
   ret = drv->API.WaitNative(drv, disp, engine);

   RETURN_EGL_EVAL(disp, ret);
}
Пример #2
0
/**
 * Match a display to a driver.  The display is initialized unless test_only is
 * true.  The matching is done by finding the first driver that can initialize
 * the display.
 */
_EGLDriver *
_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only)
{
   _EGLDriver *best_drv;

   assert(!dpy->Initialized);

   _eglLockMutex(&_eglModuleMutex);

   /* set options */
   dpy->Options.TestOnly = test_only;
   dpy->Options.UseFallback = EGL_FALSE;

   best_drv = _eglMatchAndInitialize(dpy);
   if (!best_drv) {
      dpy->Options.UseFallback = EGL_TRUE;
      best_drv = _eglMatchAndInitialize(dpy);
   }

   _eglUnlockMutex(&_eglModuleMutex);

   if (best_drv) {
      _eglLog(_EGL_DEBUG, "the best driver is %s%s",
            best_drv->Name, (test_only) ? " (test only) " : "");
      if (!test_only) {
         dpy->Driver = best_drv;
         dpy->Initialized = EGL_TRUE;
      }
   }

   return best_drv;
}
Пример #3
0
EGLBoolean EGLAPIENTRY
eglReleaseThread(void)
{
   /* unbind current contexts */
   if (!_eglIsCurrentThreadDummy()) {
      _EGLThreadInfo *t = _eglGetCurrentThread();
      EGLint api_index = t->CurrentAPIIndex;
      EGLint i;

      for (i = 0; i < _EGL_API_NUM_APIS; i++) {
         _EGLContext *ctx = t->CurrentContexts[i];
         if (ctx) {
            _EGLDisplay *disp = ctx->Resource.Display;
            _EGLDriver *drv;

            t->CurrentAPIIndex = i;

            _eglLockMutex(&disp->Mutex);
            drv = disp->Driver;
            (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
            _eglUnlockMutex(&disp->Mutex);
         }
      }

      t->CurrentAPIIndex = api_index;
   }

   _eglDestroyCurrentThread();

   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
}
Пример #4
0
/**
 * Log a message with message logger.
 * \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG.
 */
void
_eglLog(EGLint level, const char *fmtStr, ...)
{
   va_list args;
   char msg[MAXSTRING];
   int ret;

   /* one-time initialization; a little race here is fine */
   if (!logging.initialized)
      _eglInitLogger();
   if (level > logging.level || level < 0)
      return;

   _eglLockMutex(&logging.mutex);

   if (logging.logger) {
      va_start(args, fmtStr);
      ret = vsnprintf(msg, MAXSTRING, fmtStr, args);
      if (ret < 0 || ret >= MAXSTRING)
         strcpy(msg, "<message truncated>");
      va_end(args);

      logging.logger(level, msg);
      logging.num_messages++;
   }

   _eglUnlockMutex(&logging.mutex);

   if (level == _EGL_FATAL)
      exit(1); /* or abort()? */
}
Пример #5
0
static boolean
egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
                                 void *egl_image,
                                 struct st_egl_image *out)
{
   struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
   EGLImageKHR handle = (EGLImageKHR) egl_image;
   _EGLImage *img;
   struct egl_g3d_image *gimg;

   /* this is called from state trackers */
   _eglLockMutex(&gsmapi->display->Mutex);

   img = _eglLookupImage(handle, gsmapi->display);
   if (!img) {
      _eglUnlockMutex(&gsmapi->display->Mutex);
      return FALSE;
   }

   gimg = egl_g3d_image(img);

   out->texture = NULL;
   pipe_resource_reference(&out->texture, gimg->texture);
   out->level = gimg->level;
   out->layer = gimg->layer;

   _eglUnlockMutex(&gsmapi->display->Mutex);

   return TRUE;
}
Пример #6
0
/**
 * Lookup and lock a display.
 */
static INLINE _EGLDisplay *
_eglLockDisplay(EGLDisplay display)
{
   _EGLDisplay *dpy = _eglLookupDisplay(display);
   if (dpy)
      _eglLockMutex(&dpy->Mutex);
   return dpy;
}
Пример #7
0
/**
 * Return a new screen handle/ID.
 * NOTE: we never reuse these!
 */
static EGLScreenMESA
_eglAllocScreenHandle(void)
{
   EGLScreenMESA s;

   _eglLockMutex(&_eglNextScreenHandleMutex);
   s = _eglNextScreenHandle++;
   _eglUnlockMutex(&_eglNextScreenHandleMutex);

   return s;
}
Пример #8
0
/**
 * Return a new screen handle/ID.
 * NOTE: we never reuse these!
 */
static EGLScreenMESA
_eglAllocScreenHandle(void)
{
   EGLScreenMESA s;

   _eglLockMutex(&_eglNextScreenHandleMutex);
   s = _eglNextScreenHandle;
   _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
   _eglUnlockMutex(&_eglNextScreenHandleMutex);

   return s;
}
Пример #9
0
/**
 * Link a display to itself and return the handle of the link.
 * The handle can be passed to client directly.
 */
EGLDisplay
_eglLinkDisplay(_EGLDisplay *dpy)
{
   _eglLockMutex(_eglGlobal.Mutex);

   dpy->Next = _eglGlobal.DisplayList;
   _eglGlobal.DisplayList = dpy;

   _eglUnlockMutex(_eglGlobal.Mutex);

   return (EGLDisplay) dpy;
}
Пример #10
0
static INLINE void _eglFiniTSD(void)
{
   _eglLockMutex(&_egl_TSDMutex);
   if (_egl_TSDInitialized) {
      _EGLThreadInfo *t = _eglGetTSD();

      _egl_TSDInitialized = EGL_FALSE;
      if (t && _egl_FreeTSD)
         _egl_FreeTSD((void *) t);
      pthread_key_delete(_egl_TSD);
   }
   _eglUnlockMutex(&_egl_TSDMutex);
}
Пример #11
0
/**
 * Return EGL_TRUE if the given handle is a valid handle to a display.
 */
EGLBoolean
_eglCheckDisplayHandle(EGLDisplay dpy)
{
   _EGLDisplay *cur;

   _eglLockMutex(_eglGlobal.Mutex);
   cur = _eglGlobal.DisplayList;
   while (cur) {
      if (cur == (_EGLDisplay *) dpy)
         break;
      cur = cur->Next;
   }
   _eglUnlockMutex(_eglGlobal.Mutex);
   return (cur != NULL);
}
Пример #12
0
void
_eglAddAtExitCall(void (*func)(void))
{
   if (func) {

      _eglLockMutex(_eglGlobal.Mutex);

      registered = EGL_TRUE;

      assert(_eglGlobal.NumAtExitCalls < ARRAY_SIZE(_eglGlobal.AtExitCalls));
      _eglGlobal.AtExitCalls[_eglGlobal.NumAtExitCalls++] = func;

      _eglUnlockMutex(_eglGlobal.Mutex);
   }
}
Пример #13
0
/**
 * Set the log reporting level.
 */
void
_eglSetLogLevel(EGLint level)
{
   switch (level) {
   case _EGL_FATAL:
   case _EGL_WARNING:
   case _EGL_INFO:
   case _EGL_DEBUG:
      _eglLockMutex(&logging.mutex);
      logging.level = level;
      _eglUnlockMutex(&logging.mutex);
      break;
   default:
      break;
   }
}
Пример #14
0
void
_eglAddAtExitCall(void (*func)(void))
{
   if (func) {
      static EGLBoolean registered = EGL_FALSE;

      _eglLockMutex(_eglGlobal.Mutex);

      if (!registered) {
         atexit(_eglAtExit);
         registered = EGL_TRUE;
      }

      assert(_eglGlobal.NumAtExitCalls < ARRAY_SIZE(_eglGlobal.AtExitCalls));
      _eglGlobal.AtExitCalls[_eglGlobal.NumAtExitCalls++] = func;

      _eglUnlockMutex(_eglGlobal.Mutex);
   }
}
Пример #15
0
/**
 * Find the display corresponding to the specified native display id in all
 * linked displays.
 */
_EGLDisplay *
_eglFindDisplay(NativeDisplayType nativeDisplay)
{
   _EGLDisplay *dpy;

   _eglLockMutex(_eglGlobal.Mutex);

   dpy = _eglGlobal.DisplayList;
   while (dpy) {
      if (dpy->NativeDisplay == nativeDisplay) {
         _eglUnlockMutex(_eglGlobal.Mutex);
         return dpy;
      }
      dpy = dpy->Next;
   }

   _eglUnlockMutex(_eglGlobal.Mutex);

   return NULL;
}
Пример #16
0
static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
{
   if (!_egl_TSDInitialized) {
      _eglLockMutex(&_egl_TSDMutex);

      /* check again after acquiring lock */
      if (!_egl_TSDInitialized) {
         if (pthread_key_create(&_egl_TSD, (void (*)(void *)) dtor) != 0) {
            _eglUnlockMutex(&_egl_TSDMutex);
            return EGL_FALSE;
         }
         _egl_FreeTSD = dtor;
         _eglAddAtExitCall(_eglFiniTSD);
         _egl_TSDInitialized = EGL_TRUE;
      }

      _eglUnlockMutex(&_egl_TSDMutex);
   }

   return EGL_TRUE;
}
Пример #17
0
/**
 * Set the function to be called when there is a message to log.
 * Note that the function will be called with an internal lock held.
 * Recursive logging is not allowed.
 */
void
_eglSetLogProc(_EGLLogProc logger)
{
   EGLint num_messages = 0;

   _eglLockMutex(&logging.mutex);

   if (logging.logger != logger) {
      logging.logger = logger;

      num_messages = logging.num_messages;
      logging.num_messages = 0;
   }

   _eglUnlockMutex(&logging.mutex);

   if (num_messages)
      _eglLog(_EGL_DEBUG,
              "New logger installed. "
              "Messages before the new logger might not be available.");
}
Пример #18
0
/**
 * Unlink a linked display from itself.
 * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
 */
void
_eglUnlinkDisplay(_EGLDisplay *dpy)
{
   _EGLDisplay *prev;

   _eglLockMutex(_eglGlobal.Mutex);

   prev = _eglGlobal.DisplayList;
   if (prev != dpy) {
      while (prev) {
         if (prev->Next == dpy)
            break;
         prev = prev->Next;
      }
      assert(prev);
      prev->Next = dpy->Next;
   }
   else {
      _eglGlobal.DisplayList = dpy->Next;
   }

   _eglUnlockMutex(_eglGlobal.Mutex);
}
Пример #19
0
/**
 * Find the display corresponding to the specified native display, or create a
 * new one.
 */
_EGLDisplay *
_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy)
{
   _EGLDisplay *dpy;

   if (plat == _EGL_INVALID_PLATFORM)
      return NULL;

   _eglLockMutex(_eglGlobal.Mutex);

   /* search the display list first */
   dpy = _eglGlobal.DisplayList;
   while (dpy) {
      if (dpy->Platform == plat && dpy->PlatformDisplay == plat_dpy)
         break;
      dpy = dpy->Next;
   }

   /* create a new display */
   if (!dpy) {
      dpy = calloc(1, sizeof(_EGLDisplay));
      if (dpy) {
         _eglInitMutex(&dpy->Mutex);
         dpy->Platform = plat;
         dpy->PlatformDisplay = plat_dpy;

         /* add to the display list */
         dpy->Next = _eglGlobal.DisplayList;
         _eglGlobal.DisplayList = dpy;
      }
   }

   _eglUnlockMutex(_eglGlobal.Mutex);

   return dpy;
}
Пример #20
0
/**
 * Match a display to a driver.  The display is initialized unless use_probe is
 * true.
 *
 * The matching is done by finding the first driver that can initialize the
 * display, or when use_probe is true, the driver with highest score.
 */
_EGLDriver *
_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean use_probe)
{
   _EGLModule *mod;
   _EGLDriver *best_drv = NULL;
   EGLint best_score = 0;
   EGLint major, minor, i;

   _eglLockMutex(&_eglModuleMutex);

   if (!_eglAddDrivers()) {
      _eglUnlockMutex(&_eglModuleMutex);
      return EGL_FALSE;
   }

   /* match the loaded modules */
   for (i = 0; i < _eglModules->Size; i++) {
      mod = (_EGLModule *) _eglModules->Elements[i];
      if (!mod->Driver)
         break;

      if (use_probe) {
         EGLint score = (mod->Driver->Probe) ?
            mod->Driver->Probe(mod->Driver, dpy) : 1;
         if (score > best_score) {
            best_drv = mod->Driver;
            best_score = score;
         }
      }
      else {
         if (mod->Driver->API.Initialize(mod->Driver, dpy, &major, &minor)) {
            best_drv = mod->Driver;
            best_score = 100;
         }
      }
      /* perfect match */
      if (best_score >= 100)
         break;
   }

   /* load more modules */
   if (!best_drv) {
      EGLint first_unloaded = i;

      while (i < _eglModules->Size) {
         mod = (_EGLModule *) _eglModules->Elements[i];
         assert(!mod->Driver);

         if (!_eglLoadModule(mod)) {
            /* remove invalid modules */
            _eglEraseArray(_eglModules, i, _eglFreeModule);
            continue;
         }

         if (use_probe) {
            best_score = (mod->Driver->Probe) ?
               mod->Driver->Probe(mod->Driver, dpy) : 1;
         }
         else {
            if (mod->Driver->API.Initialize(mod->Driver, dpy, &major, &minor))
               best_score = 100;
         }

         if (best_score > 0) {
            best_drv = mod->Driver;
            /* loaded modules come before unloaded ones */
            if (first_unloaded != i) {
               void *tmp = _eglModules->Elements[i];
               _eglModules->Elements[i] =
                  _eglModules->Elements[first_unloaded];
               _eglModules->Elements[first_unloaded] = tmp;
            }
            break;
         }
         else {
            _eglUnloadModule(mod);
            i++;
         }
      }
   }

   _eglUnlockMutex(&_eglModuleMutex);

   if (best_drv) {
      _eglLog(_EGL_DEBUG, "the best driver is %s (score %d)",
            best_drv->Name, best_score);
      if (!use_probe) {
         dpy->Driver = best_drv;
         dpy->Initialized = EGL_TRUE;
         dpy->APImajor = major;
         dpy->APIminor = minor;
      }
   }

   return best_drv;
}