glamor.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*
  2. * Copyright © 2008 Intel Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. *
  23. * Authors:
  24. * Eric Anholt <eric@anholt.net>
  25. * Zhigang Gong <zhigang.gong@linux.intel.com>
  26. *
  27. */
  28. /** @file glamor.c
  29. * This file covers the initialization and teardown of glamor, and has various
  30. * functions not responsible for performing rendering.
  31. */
  32. #include <stdlib.h>
  33. #include "glamor_priv.h"
  34. static DevPrivateKeyRec glamor_screen_private_key_index;
  35. DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
  36. static DevPrivateKeyRec glamor_pixmap_private_key_index;
  37. DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
  38. /**
  39. * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
  40. *
  41. * @param drawable the drawable being requested.
  42. *
  43. * This function returns the backing pixmap for a drawable, whether it is a
  44. * redirected window, unredirected window, or already a pixmap. Note that
  45. * coordinate translation is needed when drawing to the backing pixmap of a
  46. * redirected window, and the translation coordinates are provided by calling
  47. * exaGetOffscreenPixmap() on the drawable.
  48. */
  49. PixmapPtr
  50. glamor_get_drawable_pixmap(DrawablePtr drawable)
  51. {
  52. if (drawable->type == DRAWABLE_WINDOW)
  53. return drawable->pScreen->GetWindowPixmap((WindowPtr) drawable);
  54. else
  55. return (PixmapPtr) drawable;
  56. }
  57. _X_EXPORT void
  58. glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
  59. {
  60. glamor_pixmap_private *pixmap_priv;
  61. glamor_screen_private *glamor_priv =
  62. glamor_get_screen_private(pixmap->drawable.pScreen);
  63. pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
  64. glamor_pixmap_private_key);
  65. if (pixmap_priv == NULL) {
  66. pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
  67. glamor_set_pixmap_private(pixmap, pixmap_priv);
  68. pixmap_priv->base.pixmap = pixmap;
  69. pixmap_priv->base.glamor_priv = glamor_priv;
  70. }
  71. pixmap_priv->type = type;
  72. pixmap_priv->base.box.x1 = 0;
  73. pixmap_priv->base.box.x2 = pixmap->drawable.width;
  74. pixmap_priv->base.box.y1 = 0;
  75. pixmap_priv->base.box.y2 = pixmap->drawable.height;
  76. }
  77. _X_EXPORT void
  78. glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
  79. {
  80. ScreenPtr screen = pixmap->drawable.pScreen;
  81. glamor_pixmap_private *pixmap_priv;
  82. glamor_screen_private *glamor_priv;
  83. glamor_pixmap_fbo *fbo;
  84. GLenum format;
  85. glamor_priv = glamor_get_screen_private(screen);
  86. pixmap_priv = glamor_get_pixmap_private(pixmap);
  87. if (pixmap_priv->base.fbo) {
  88. fbo = glamor_pixmap_detach_fbo(pixmap_priv);
  89. glamor_destroy_fbo(fbo);
  90. }
  91. format = gl_iformat_for_pixmap(pixmap);
  92. fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
  93. pixmap->drawable.height, format, tex, 0);
  94. if (fbo == NULL) {
  95. ErrorF("XXX fail to create fbo.\n");
  96. return;
  97. }
  98. glamor_pixmap_attach_fbo(pixmap, fbo);
  99. }
  100. void
  101. glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
  102. {
  103. glamor_pixmap_private *pixmap_priv;
  104. glamor_screen_private *glamor_priv;
  105. glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
  106. pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
  107. glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
  108. pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
  109. pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
  110. glamor_priv->back_pixmap = back_pixmap;
  111. }
  112. uint32_t
  113. glamor_get_pixmap_texture(PixmapPtr pixmap)
  114. {
  115. glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
  116. if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY)
  117. return 0;
  118. return pixmap_priv->base.fbo->tex;
  119. }
  120. PixmapPtr
  121. glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
  122. unsigned int usage)
  123. {
  124. PixmapPtr pixmap;
  125. glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
  126. glamor_pixmap_private *pixmap_priv;
  127. glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
  128. glamor_pixmap_fbo *fbo = NULL;
  129. int pitch;
  130. GLenum format;
  131. if (w > 32767 || h > 32767)
  132. return NullPixmap;
  133. if ((usage == GLAMOR_CREATE_PIXMAP_CPU
  134. || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64)
  135. || (w == 0 && h == 0)
  136. || !glamor_check_pixmap_fbo_depth(depth))
  137. || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
  138. !glamor_check_fbo_size(glamor_priv, w, h)))
  139. return fbCreatePixmap(screen, w, h, depth, usage);
  140. else
  141. pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
  142. pixmap_priv = calloc(1, sizeof(*pixmap_priv));
  143. if (!pixmap_priv) {
  144. fbDestroyPixmap(pixmap);
  145. return fbCreatePixmap(screen, w, h, depth, usage);
  146. }
  147. glamor_set_pixmap_private(pixmap, pixmap_priv);
  148. if (usage == GLAMOR_CREATE_PIXMAP_MAP)
  149. type = GLAMOR_MEMORY_MAP;
  150. pixmap_priv->base.pixmap = pixmap;
  151. pixmap_priv->base.glamor_priv = glamor_priv;
  152. format = gl_iformat_for_pixmap(pixmap);
  153. pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
  154. screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
  155. if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
  156. pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
  157. pixmap_priv->base.box.x1 = 0;
  158. pixmap_priv->base.box.y1 = 0;
  159. pixmap_priv->base.box.x2 = w;
  160. pixmap_priv->base.box.y2 = h;
  161. return pixmap;
  162. }
  163. else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
  164. glamor_check_fbo_size(glamor_priv, w, h))
  165. {
  166. pixmap_priv->type = type;
  167. pixmap_priv->base.box.x1 = 0;
  168. pixmap_priv->base.box.y1 = 0;
  169. pixmap_priv->base.box.x2 = w;
  170. pixmap_priv->base.box.y2 = h;
  171. fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
  172. } else {
  173. int tile_size = glamor_priv->max_fbo_size;
  174. DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size);
  175. pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
  176. fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
  177. tile_size, tile_size, pixmap_priv);
  178. }
  179. if (fbo == NULL) {
  180. fbDestroyPixmap(pixmap);
  181. free(pixmap_priv);
  182. return fbCreatePixmap(screen, w, h, depth, usage);
  183. }
  184. glamor_pixmap_attach_fbo(pixmap, fbo);
  185. return pixmap;
  186. }
  187. void
  188. glamor_destroy_textured_pixmap(PixmapPtr pixmap)
  189. {
  190. if (pixmap->refcnt == 1) {
  191. glamor_pixmap_private *pixmap_priv;
  192. pixmap_priv = glamor_get_pixmap_private(pixmap);
  193. if (pixmap_priv != NULL)
  194. glamor_pixmap_destroy_fbo(pixmap_priv);
  195. }
  196. }
  197. Bool
  198. glamor_destroy_pixmap(PixmapPtr pixmap)
  199. {
  200. glamor_screen_private
  201. *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
  202. if (glamor_priv->dri3_enabled)
  203. glamor_egl_destroy_textured_pixmap(pixmap);
  204. else
  205. glamor_destroy_textured_pixmap(pixmap);
  206. return fbDestroyPixmap(pixmap);
  207. }
  208. void
  209. glamor_block_handler(ScreenPtr screen)
  210. {
  211. glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
  212. glamor_make_current(glamor_priv);
  213. glamor_priv->tick++;
  214. glFlush();
  215. glamor_fbo_expire(glamor_priv);
  216. if (glamor_priv->state == RENDER_STATE
  217. && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
  218. glamor_priv->state = IDLE_STATE;
  219. glamor_priv->render_idle_cnt = 0;
  220. }
  221. }
  222. static void
  223. _glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
  224. {
  225. glamor_screen_private *glamor_priv = data;
  226. glamor_make_current(glamor_priv);
  227. glFlush();
  228. }
  229. static void
  230. _glamor_wakeup_handler(void *data, int result, void *last_select_mask)
  231. {
  232. }
  233. static void
  234. glamor_set_debug_level(int *debug_level)
  235. {
  236. char *debug_level_string;
  237. debug_level_string = getenv("GLAMOR_DEBUG");
  238. if (debug_level_string
  239. && sscanf(debug_level_string, "%d", debug_level) == 1)
  240. return;
  241. *debug_level = 0;
  242. }
  243. int glamor_debug_level;
  244. /**
  245. * Creates any pixmaps used internally by glamor, since those can't be
  246. * allocated at ScreenInit time.
  247. */
  248. static Bool
  249. glamor_create_screen_resources(ScreenPtr screen)
  250. {
  251. glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
  252. Bool ret = TRUE;
  253. screen->CreateScreenResources =
  254. glamor_priv->saved_procs.create_screen_resources;
  255. if (screen->CreateScreenResources)
  256. ret = screen->CreateScreenResources(screen);
  257. screen->CreateScreenResources = glamor_create_screen_resources;
  258. if (!glamor_realize_glyph_caches(screen)) {
  259. ErrorF("Failed to initialize glyph cache\n");
  260. ret = FALSE;
  261. }
  262. return ret;
  263. }
  264. /** Set up glamor for an already-configured GL context. */
  265. Bool
  266. glamor_init(ScreenPtr screen, unsigned int flags)
  267. {
  268. glamor_screen_private *glamor_priv;
  269. int gl_version;
  270. int max_viewport_size[2];
  271. #ifdef RENDER
  272. PictureScreenPtr ps = GetPictureScreenIfSet(screen);
  273. #endif
  274. if (flags & ~GLAMOR_VALID_FLAGS) {
  275. ErrorF("glamor_init: Invalid flags %x\n", flags);
  276. return FALSE;
  277. }
  278. glamor_priv = calloc(1, sizeof(*glamor_priv));
  279. if (glamor_priv == NULL)
  280. return FALSE;
  281. glamor_priv->flags = flags;
  282. if (flags & GLAMOR_INVERTED_Y_AXIS) {
  283. glamor_priv->yInverted = TRUE;
  284. }
  285. else
  286. glamor_priv->yInverted = FALSE;
  287. if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
  288. LogMessage(X_WARNING,
  289. "glamor%d: Failed to allocate screen private\n",
  290. screen->myNum);
  291. goto fail;
  292. }
  293. glamor_set_screen_private(screen, glamor_priv);
  294. if (!dixRegisterPrivateKey(glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
  295. LogMessage(X_WARNING,
  296. "glamor%d: Failed to allocate pixmap private\n",
  297. screen->myNum);
  298. goto fail;;
  299. }
  300. if (epoxy_is_desktop_gl())
  301. glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
  302. else
  303. glamor_priv->gl_flavor = GLAMOR_GL_ES2;
  304. gl_version = epoxy_gl_version();
  305. /* Would be nice to have a cleaner test for GLSL 1.30 support,
  306. * but for now this should suffice
  307. */
  308. if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && gl_version >= 30)
  309. glamor_priv->glsl_version = 130;
  310. else
  311. glamor_priv->glsl_version = 120;
  312. /* We'd like to require GL_ARB_map_buffer_range or
  313. * GL_OES_map_buffer_range, since it offers more information to
  314. * the driver than plain old glMapBuffer() or glBufferSubData().
  315. * It's been supported on Mesa on the desktop since 2009 and on
  316. * GLES2 since October 2012. It's supported on Apple's iOS
  317. * drivers for SGX535 and A7, but apparently not on most Android
  318. * devices (the OES extension spec wasn't released until June
  319. * 2012).
  320. *
  321. * 82% of 0 A.D. players (desktop GL) submitting hardware reports
  322. * have support for it, with most of the ones lacking it being on
  323. * Windows with Intel 4-series (G45) graphics or older.
  324. */
  325. if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
  326. if (gl_version < 21) {
  327. ErrorF("Require OpenGL version 2.1 or later.\n");
  328. goto fail;
  329. }
  330. } else {
  331. if (gl_version < 20) {
  332. ErrorF("Require Open GLES2.0 or later.\n");
  333. goto fail;
  334. }
  335. if (!epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) {
  336. ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
  337. goto fail;
  338. }
  339. }
  340. glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug");
  341. glamor_priv->has_pack_invert =
  342. epoxy_has_gl_extension("GL_MESA_pack_invert");
  343. glamor_priv->has_fbo_blit =
  344. epoxy_has_gl_extension("GL_EXT_framebuffer_blit");
  345. glamor_priv->has_map_buffer_range =
  346. epoxy_has_gl_extension("GL_ARB_map_buffer_range");
  347. glamor_priv->has_buffer_storage =
  348. epoxy_has_gl_extension("GL_ARB_buffer_storage");
  349. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
  350. glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size);
  351. glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]);
  352. glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[1]);
  353. #ifdef MAX_FBO_SIZE
  354. glamor_priv->max_fbo_size = MAX_FBO_SIZE;
  355. #endif
  356. glamor_set_debug_level(&glamor_debug_level);
  357. /* If we are using egl screen, call egl screen init to
  358. * register correct close screen function. */
  359. if (flags & GLAMOR_USE_EGL_SCREEN) {
  360. glamor_egl_screen_init(screen, &glamor_priv->ctx);
  361. } else {
  362. if (!glamor_glx_screen_init(&glamor_priv->ctx))
  363. goto fail;
  364. }
  365. glamor_priv->saved_procs.close_screen = screen->CloseScreen;
  366. screen->CloseScreen = glamor_close_screen;
  367. glamor_priv->saved_procs.create_screen_resources =
  368. screen->CreateScreenResources;
  369. screen->CreateScreenResources = glamor_create_screen_resources;
  370. if (!glamor_font_init(screen))
  371. goto fail;
  372. if (flags & GLAMOR_USE_SCREEN) {
  373. if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
  374. _glamor_wakeup_handler,
  375. glamor_priv)) {
  376. goto fail;
  377. }
  378. glamor_priv->saved_procs.create_gc = screen->CreateGC;
  379. screen->CreateGC = glamor_create_gc;
  380. glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
  381. screen->CreatePixmap = glamor_create_pixmap;
  382. glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
  383. screen->DestroyPixmap = glamor_destroy_pixmap;
  384. glamor_priv->saved_procs.get_spans = screen->GetSpans;
  385. screen->GetSpans = glamor_get_spans;
  386. glamor_priv->saved_procs.get_image = screen->GetImage;
  387. screen->GetImage = glamor_get_image;
  388. glamor_priv->saved_procs.change_window_attributes =
  389. screen->ChangeWindowAttributes;
  390. screen->ChangeWindowAttributes = glamor_change_window_attributes;
  391. glamor_priv->saved_procs.copy_window = screen->CopyWindow;
  392. screen->CopyWindow = glamor_copy_window;
  393. glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
  394. screen->BitmapToRegion = glamor_bitmap_to_region;
  395. }
  396. #ifdef RENDER
  397. if (flags & GLAMOR_USE_PICTURE_SCREEN) {
  398. glamor_priv->saved_procs.composite = ps->Composite;
  399. ps->Composite = glamor_composite;
  400. glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
  401. ps->Trapezoids = glamor_trapezoids;
  402. glamor_priv->saved_procs.triangles = ps->Triangles;
  403. ps->Triangles = glamor_triangles;
  404. glamor_priv->saved_procs.addtraps = ps->AddTraps;
  405. ps->AddTraps = glamor_add_traps;
  406. }
  407. glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
  408. ps->CompositeRects = glamor_composite_rectangles;
  409. glamor_priv->saved_procs.glyphs = ps->Glyphs;
  410. ps->Glyphs = glamor_glyphs;
  411. glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
  412. ps->UnrealizeGlyph = glamor_glyph_unrealize;
  413. glamor_priv->saved_procs.create_picture = ps->CreatePicture;
  414. ps->CreatePicture = glamor_create_picture;
  415. glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
  416. ps->DestroyPicture = glamor_destroy_picture;
  417. glamor_init_composite_shaders(screen);
  418. #endif
  419. glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
  420. screen->SetWindowPixmap = glamor_set_window_pixmap;
  421. glamor_init_vbo(screen);
  422. glamor_init_pixmap_fbo(screen);
  423. glamor_init_solid_shader(screen);
  424. glamor_init_tile_shader(screen);
  425. #ifdef GLAMOR_TRAPEZOID_SHADER
  426. glamor_init_trapezoid_shader(screen);
  427. #endif
  428. glamor_init_finish_access_shaders(screen);
  429. #ifdef GLAMOR_GRADIENT_SHADER
  430. glamor_init_gradient_shader(screen);
  431. #endif
  432. glamor_pixmap_init(screen);
  433. glamor_glyphs_init(screen);
  434. glamor_priv->screen = screen;
  435. return TRUE;
  436. fail:
  437. free(glamor_priv);
  438. glamor_set_screen_private(screen, NULL);
  439. return FALSE;
  440. }
  441. static void
  442. glamor_release_screen_priv(ScreenPtr screen)
  443. {
  444. glamor_screen_private *glamor_priv;
  445. glamor_priv = glamor_get_screen_private(screen);
  446. #ifdef RENDER
  447. glamor_fini_composite_shaders(screen);
  448. #endif
  449. glamor_fini_vbo(screen);
  450. glamor_fini_pixmap_fbo(screen);
  451. glamor_fini_solid_shader(screen);
  452. glamor_fini_tile_shader(screen);
  453. #ifdef GLAMOR_TRAPEZOID_SHADER
  454. glamor_fini_trapezoid_shader(screen);
  455. #endif
  456. glamor_fini_finish_access_shaders(screen);
  457. #ifdef GLAMOR_GRADIENT_SHADER
  458. glamor_fini_gradient_shader(screen);
  459. #endif
  460. glamor_pixmap_fini(screen);
  461. free(glamor_priv);
  462. glamor_set_screen_private(screen, NULL);
  463. }
  464. _X_EXPORT void
  465. glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
  466. {
  467. glamor_pixmap_private *old_priv;
  468. glamor_pixmap_fbo *fbo;
  469. old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
  470. if (priv) {
  471. assert(old_priv == NULL);
  472. }
  473. else {
  474. if (old_priv == NULL)
  475. return;
  476. fbo = glamor_pixmap_detach_fbo(old_priv);
  477. glamor_purge_fbo(fbo);
  478. free(old_priv);
  479. }
  480. dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv);
  481. }
  482. Bool
  483. glamor_close_screen(ScreenPtr screen)
  484. {
  485. glamor_screen_private *glamor_priv;
  486. PixmapPtr screen_pixmap;
  487. int flags;
  488. #ifdef RENDER
  489. PictureScreenPtr ps = GetPictureScreenIfSet(screen);
  490. #endif
  491. glamor_priv = glamor_get_screen_private(screen);
  492. flags = glamor_priv->flags;
  493. glamor_glyphs_fini(screen);
  494. screen->CloseScreen = glamor_priv->saved_procs.close_screen;
  495. screen->CreateScreenResources =
  496. glamor_priv->saved_procs.create_screen_resources;
  497. if (flags & GLAMOR_USE_SCREEN) {
  498. screen->CreateGC = glamor_priv->saved_procs.create_gc;
  499. screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
  500. screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
  501. screen->GetSpans = glamor_priv->saved_procs.get_spans;
  502. screen->ChangeWindowAttributes =
  503. glamor_priv->saved_procs.change_window_attributes;
  504. screen->CopyWindow = glamor_priv->saved_procs.copy_window;
  505. screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
  506. }
  507. #ifdef RENDER
  508. if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
  509. ps->Composite = glamor_priv->saved_procs.composite;
  510. ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
  511. ps->Triangles = glamor_priv->saved_procs.triangles;
  512. ps->CreatePicture = glamor_priv->saved_procs.create_picture;
  513. }
  514. ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
  515. ps->Glyphs = glamor_priv->saved_procs.glyphs;
  516. ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
  517. screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
  518. #endif
  519. screen_pixmap = screen->GetScreenPixmap(screen);
  520. glamor_set_pixmap_private(screen_pixmap, NULL);
  521. if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
  522. glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);
  523. glamor_release_screen_priv(screen);
  524. return screen->CloseScreen(screen);
  525. }
  526. void
  527. glamor_fini(ScreenPtr screen)
  528. {
  529. /* Do nothing currently. */
  530. }
  531. void
  532. glamor_enable_dri3(ScreenPtr screen)
  533. {
  534. glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
  535. glamor_priv->dri3_enabled = TRUE;
  536. }
  537. Bool
  538. glamor_supports_pixmap_import_export(ScreenPtr screen)
  539. {
  540. glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
  541. return glamor_priv->dri3_enabled;
  542. }
  543. _X_EXPORT int
  544. glamor_fd_from_pixmap(ScreenPtr screen,
  545. PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
  546. {
  547. glamor_pixmap_private *pixmap_priv;
  548. glamor_screen_private *glamor_priv =
  549. glamor_get_screen_private(pixmap->drawable.pScreen);
  550. pixmap_priv = glamor_get_pixmap_private(pixmap);
  551. if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
  552. return -1;
  553. switch (pixmap_priv->type) {
  554. case GLAMOR_TEXTURE_DRM:
  555. case GLAMOR_TEXTURE_ONLY:
  556. if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
  557. return -1;
  558. return glamor_egl_dri3_fd_name_from_tex(screen,
  559. pixmap,
  560. pixmap_priv->base.fbo->tex,
  561. FALSE, stride, size);
  562. default:
  563. break;
  564. }
  565. return -1;
  566. }
  567. int
  568. glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
  569. {
  570. glamor_pixmap_private *pixmap_priv;
  571. glamor_screen_private *glamor_priv =
  572. glamor_get_screen_private(pixmap->drawable.pScreen);
  573. pixmap_priv = glamor_get_pixmap_private(pixmap);
  574. if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
  575. return -1;
  576. switch (pixmap_priv->type) {
  577. case GLAMOR_TEXTURE_DRM:
  578. case GLAMOR_TEXTURE_ONLY:
  579. if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
  580. return -1;
  581. return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
  582. pixmap,
  583. pixmap_priv->base.fbo->tex,
  584. TRUE, stride, size);
  585. default:
  586. break;
  587. }
  588. return -1;
  589. }