Compare commits

...

20 Commits

Author SHA1 Message Date
Chad Versace
8cb2b5c37a CHROMIUM: i965: Implement EGL_KHR_mutable_render_buffer
Tested with a low-latency handwriting application on Android Nougat on
the Chrome OS Pixelbook (codename Eve) with Kabylake.

BUG=b:77899911
TEST=No android-cts-7.1 regressions on Eve.

Change-Id: Ia816fa6b0a1158f81e5b63477451bf337c2001aa
2018-07-30 10:50:41 -07:00
Chad Versace
6158e78240 CHROMIUM: egl/android: Implement EGL_KHR_mutable_render_buffer
Specifically, implement the extension DRI_MutableRenderBufferLoader.
However, the loader enables EGL_KHR_mutable_render_buffer only if the
DRI driver implements its half of the extension,
DRI_MutableRenderBufferDriver.

BUG=b:77899911
TEST=No android-cts-7.1 regressions on Eve.

Change-Id: I7fe68a5a674d1707b1e7251d900b3affd5dd7660
2018-07-30 10:50:41 -07:00
Chad Versace
c689a23c77 CHROMIUM: egl/main: Add bits for EGL_KHR_mutable_render_buffer
A follow-up patch enables EGL_KHR_mutable_render_buffer for Android.
This patch is separate from the Android patch because I think it's
easier to review the platform-independent bits separately.

BUG=b:77899911
TEST=No android-cts-7.1 regressions on Eve.

Change-Id: I07470f2862796611b141f69f47f935b97b0e04a1
2018-07-30 10:50:41 -07:00
Chad Versace
0cbe8ad97d CHROMIUM: dri: Add param driCreateConfigs(mutable_render_buffer)
If set, then the config will have __DRI_ATTRIB_MUTABLE_RENDER_BUFFER,
which translates to EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.

Not used yet.

BUG=b:77899911
TEST=No android-cts-7.1 regressions on Eve.

Change-Id: Icdf35794f3e9adf31e1f85740b87ce155efe1491
2018-07-30 10:50:41 -07:00
Chad Versace
f57e2bf44e CHROMIUM: dri: Define DRI_MutableRenderBuffer extensions
Define extensions DRI_MutableRenderBufferDriver and
DRI_MutableRenderBufferLoader. These are the two halves for
EGL_KHR_mutable_render_buffer.

Outside the DRI code there is one additional change.  Add
gl_config::mutableRenderBuffer to match
__DRI_ATTRIB_MUTABLE_RENDER_BUFFER. Neither are used yet.

BUG=b:77899911
TEST=No android-cts-7.1 regressions on Eve.

Change-Id: I4ca03d81e4557380b19c44d8d799a7cc9365d928
2018-07-30 10:50:40 -07:00
Chad Versace
3274c56585 CHROMIUM: egl/dri2: In dri2_make_current, return early on failure
This pulls an 'else' block into the function's main body, making the
code easier to follow.

Without this change, the upcoming EGL_KHR_mutable_render_buffer patch
transforms dri2_make_current() into spaghetti.

BUG=b:77899911
TEST=No android-cts-7.1 regressions on Eve.

Change-Id: I26be2b7a8e78a162dcd867a44f62d6f48b9a8e4d
2018-07-30 09:32:54 -07:00
Chad Versace
0a957c2822 CHROMIUM: egl: Simplify queries for EGL_RENDER_BUFFER
There exist *two* queryable EGL_RENDER_BUFFER states in EGL:
eglQuerySurface(EGL_RENDER_BUFFER) and
eglQueryContext(EGL_RENDER_BUFFER).

These changes eliminate potentially very fragile code in the upcoming
EGL_KHR_mutable_render_buffer implementation.

* eglQuerySurface(EGL_RENDER_BUFFER)

  The implementation of eglQuerySurface(EGL_RENDER_BUFFER) contained
  abstruse logic which required comprehending the specification
  complexities of how the two EGL_RENDER_BUFFER states interact.  The
  function sometimes returned _EGLContext::WindowRenderBuffer, sometimes
  _EGLSurface::RenderBuffer. Why? The function tried to encode the
  actual logic from the EGL spec. When did the function return which
  variable? Go study the EGL spec, hope you understand it, then hope
  Mesa mutated the EGL_RENDER_BUFFER state in all the correct places.
  Have fun.

  To simplify eglQuerySurface(EGL_RENDER_BUFFER), and to improve
  confidence in its correctness, flatten its indirect logic. For pixmap
  and pbuffer surfaces, simply return a hard-coded literal value, as the
  spec suggests. For window surfaces, simply return
  _EGLSurface::RequestedRenderBuffer.  Nothing difficult here.

* eglQueryContext(EGL_RENDER_BUFFER)

  The implementation of this suffered from the same issues as
  eglQuerySurface, and the solution is the same.  confidence in its
  correctness, flatten its indirect logic. For pixmap and pbuffer
  surfaces, simply return a hard-coded literal value, as the spec
  suggests. For window surfaces, simply return
  _EGLSurface::ActiveRenderBuffer.

BUG=b:77899911
TEST=No android-cts-7.1 regressions on Eve.

Change-Id: Ic5f2ab1952f26a87081bc4f78bc7fa96734c8f2a
2018-07-30 09:18:28 -07:00
Chad Versace
6ac5d83a6c FROMLIST: gallium/auxiliary: Fix Autotools on Android (v2)
Problem 1: u_debug_stack_android.cpp transitively included
"pipe/p_compiler.h", but src/gallium/include was missing from the C++
include path.

Problem 2: Add -std=c++11 to AM_CXXFLAGS. Android's libbacktrace headers
require C++11, but the Android toolchain (at least in the Chrome OS SDK)
does not enable C++11 by default.

v2: Add -std=c++11.

Cc: Gurchetan Singh <gurchetansingh@chromium.org>
Cc: Eric Engestrom <eric.engestrom@intel.com>
Archived-At: https://lists.freedesktop.org/archives/mesa-dev/2018-July/200979.html
(am from https://patchwork.freedesktop.org/patch/240805/)

Fixes the build for betty-arcnext.

BUG=b:77235812
TEST=emerge-betty-arcnext arc-mesa

Change-Id: Idd30463f3941d7b119207aa5afd7e37e69b0a5ae
Reviewed-on: https://chromium-review.googlesource.com/1149449
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Chad Versace <chadversary@chromium.org>
2018-07-25 01:54:44 +00:00
Chad Versace
53ba2797ee FROMLIST: drisw: Fix build on Android Nougat
In commit cf54bd5e8, dri_sw_winsys.c began using <sys/shm.h> to support
the new functions putImageShm, getImageShm in DRI_SWRastLoader. But
Android began supporting System V shared memory only in Oreo. Nougat has
no shm headers.

Fix the build by ifdef'ing out the shm code on Nougat.

Fixes: cf54bd5e8 "drisw: use shared memory when possible"
Cc: Marc-André Lureau <marcandre.lureau@gmail.com>
Cc: Dave Airlie <airlied@redhat.com>
Archived-At: https://lists.freedesktop.org/archives/mesa-dev/2018-July/200705.html
(am from https://patchwork.freedesktop.org/patch/240173/)

Fixes the build for betty.

BUG=b:77235812
TEST=emerge-betty arc-mesa

Change-Id: I5fc7214cd30fdea49b69cdc860cefd622466c7da
Reviewed-on: https://chromium-review.googlesource.com/1146074
Tested-by: Chad Versace <chadversary@chromium.org>
Trybot-Ready: Chad Versace <chadversary@chromium.org>
Reviewed-by: Ilja H. Friedel <ihf@chromium.org>
Commit-Queue: Ilja H. Friedel <ihf@chromium.org>
2018-07-21 16:51:26 +00:00
Lepton Wu
58cbc48eac UPSTREAM: virgl: Fix flush in virgl_encoder_inline_write.
The current code is buggy: if there are only 12 dwords left in cbuf,
we emit a zero data length command which will be rejected by virglrenderer.
Fix it by calling flush in this case.

Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Dave Airlie <airlied@redhat.com>
(cherry-picked from commit 04e278f793)

BUG=b:111521569

Change-Id: Ie952ece5e31ee94c5fb7e6ecb3e1de807a21763b
Reviewed-on: https://chromium-review.googlesource.com/1140419
Tested-by: Lepton Wu <lepton@chromium.org>
Trybot-Ready: Lepton Wu <lepton@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Commit-Queue: Lepton Wu <lepton@chromium.org>
2018-07-17 23:25:10 +00:00
Lepton Wu
c884f74c5f CHROMIUM: platform_android: use general fallback.
Instead of handling software fallback inside platform_android, just
let EGL framework to handle it. With this, we still can fall back
to software driver when hardware driver actually doesn't work.

BUG=b:77302150
TEST=manual - make sure betty still boot without virgl driver.

Change-Id: I5d514f67c9dc6f68661e03fd9fc9546acd7277bd
Reviewed-on: https://chromium-review.googlesource.com/1004006
Commit-Ready: Lepton Wu <lepton@chromium.org>
Tested-by: Lepton Wu <lepton@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
(cherry picked from commit b16fbdb135)
[chadversary: Simplify by dropping unneeded 'swrast' param.]

BUG=b:77235812
TEST=emerge-grunt arc-mesa; emerge-eve arc-mesa

Change-Id: Ib896c3f16dcd5fdddc0a7eb9e72caa7f2037c2f3
Reviewed-on: https://chromium-review.googlesource.com/1105708
Commit-Queue: Chad Versace <chadversary@chromium.org>
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Ilja H. Friedel <ihf@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
2018-07-12 18:17:24 +00:00
Emil Velikov
ca6dc3b7f4 FROMLIST: egl/android: remove HAL_PIXEL_FORMAT_BGRA_8888 support
As said in the EGL_KHR_platform_android extensions

    For each EGLConfig that belongs to the Android platform, the
    EGL_NATIVE_VISUAL_ID attribute is an Android window format, such as
    WINDOW_FORMAT_RGBA_8888.

Although it should be applicable overall.

Even though we use HAL_PIXEL_FORMAT here, those are numerically
identical to the  WINDOW_FORMAT_ and AHARDWAREBUFFER_FORMAT_ ones.

Barring the said format of course. That one is only listed in HAL.

Keep in mind that even if we try to use the said format, you'll get
caught by droid_create_surface(). The function compares the format of
the underlying window, against the NATIVE_VISUAL_ID of the config.

Unfortunatelly it only prints a warning, rather than error out, likely
leading to visual corruption.

While SDL will even call ANativeWindow_setBuffersGeometry() with the
wrong format, and conviniently ignore the [expected] failure.

Cc: mesa-stable@lists.freedesktop.org
Cc: Chad Versace <chadversary@google.com>
Cc: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Acked-by: Tomasz Figa <tfiga@chromium.org>
(am from https://patchwork.freedesktop.org/patch/166176/)
(tfiga: Remove only respective EGL config, leave EGL image as is.)

BUG=b:33533853
TEST=dEQP-EGL.functional.*.rgba8888_window tests pass on eve

Change-Id: I8eacfe852ede88b24c1a45bff1445aacd86f6992
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/582263
Reviewed-by: Chad Versace <chadversary@chromium.org>
(cherry picked from commit 42c96d393b)

BUG=b:77235812
TEST=emerge-grunt arc-mesa; emerge-eve arc-mesa

Change-Id: I74e91a3621fcc9c80633cf512a8d08782ac6e1d7
Reviewed-on: https://chromium-review.googlesource.com/1105707
Commit-Queue: Chad Versace <chadversary@chromium.org>
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
2018-07-12 18:17:23 +00:00
Stéphane Marchesin
f7f64ad0ac CHROMIUM: egl/android: Support opening render nodes from within EGL
This patch adds support for opening render nodes directly from within
display initialization, Instead of relying on private interfaces
provided by gralloc.

In addition to having better separation from gralloc and being able to
use different render nodes for allocation and rendering, this also fixes
problems encountered when using the same DRI FD for gralloc and Mesa,
when both stepped each over another because of shared GEM handle
namespace.

BUG=b:29036398
TEST=No significant regressions in dEQP inside the container

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/367215
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
(cherry picked from commit 1171bddb74)

BUG=b:77235812
TEST=emerge-grunt arc-mesa; emerge-eve arc-mesa

Change-Id: Ib76d2f02077e3f679ca86d31fc999bff3a46edf0
Reviewed-on: https://chromium-review.googlesource.com/1105706
Commit-Queue: Chad Versace <chadversary@chromium.org>
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
2018-07-12 18:17:22 +00:00
Tapani Pälli
97636c85f9 FROMLIST: glcpp: Hack to handle expressions in #line directives.
GLSL ES 320 technically allows #line to have arbitrary expression trees
rather than integer literal constants, unlike the C and C++ preprocessor.
This is likely a completely unused feature that does not make sense.

However, Android irritatingly mandates this useless behavior, so this
patch implements a hack to try and support it.

We handle a single expression:

    #line <line number expression>

but we avoid handling the double expression:

    #line <line number expression> <source string expression>

because this is an ambiguous grammar.  Instead, we handle the case that
wraps both in parenthesis, which is actually well defined:

    #line (<line number expression>) (<source string expression>)

With this change following tests pass:

   dEQP-GLES3.functional.shaders.preprocessor.builtin.line_expression_vertex
   dEQP-GLES3.functional.shaders.preprocessor.builtin.line_expression_fragment
   dEQP-GLES3.functional.shaders.preprocessor.builtin.line_and_file_expression_vertex
   dEQP-GLES3.functional.shaders.preprocessor.builtin.line_and_file_expression_fragment

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>

BUG=b:33352633
BUG=b:33247335
TEST=affected tests passing on CTS 7.1_r1 sentry

Reviewed-on: https://chromium-review.googlesource.com/427305
Tested-by: Haixia Shi <hshi@chromium.org>
Reviewed-by: Ilja H. Friedel <ihf@chromium.org>
Commit-Queue: Haixia Shi <hshi@chromium.org>
Trybot-Ready: Haixia Shi <hshi@chromium.org>
(cherry picked from commit 5ec83db3fc)

BUG=b:77235812
TEST=emerge-grunt arc-mesa; emerge-eve arc-mesa

Change-Id: Ie12a03e7642ac4f5d79e0b6b20e16d7653c3395c
Reviewed-on: https://chromium-review.googlesource.com/1105705
Commit-Queue: Chad Versace <chadversary@chromium.org>
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
2018-07-12 18:17:21 +00:00
Stéphane Marchesin
f408dc0e46 CHROMIUM: glsl: Avoid crash when overflowing the samplers array
Fixes a crash when we have too many samplers.

BUG=chromium:141901
TEST=by hand

Signed-off-by: Prince Agyeman <prince.agyeman@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: James Ausmus <james.ausmus@intel.com>
(cherry picked from commit 403ab71152)

BUG=b:77235812
TEST=emerge-grunt arc-mesa; emerge-eve arc-mesa

Change-Id: I8ffebdae3bdab68da4277193fe367959ab719796
Reviewed-on: https://chromium-review.googlesource.com/1105702
Commit-Queue: Chad Versace <chadversary@chromium.org>
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
2018-07-12 18:17:20 +00:00
Chad Versace
15656ccb9e UPSTREAM: anv/android: Fix type error in call to vk_errorf()
In a single call to vk_errorf() in the Android code, the arguments were
swapped. The bug has existed since day one. Chrome OS used to forgive
the warning, but it is now a compilation error.

CC: <mesa-stable@lists.freedesktop.org>
Fixes: 053d4c32 "anv: Implement VK_ANDROID_native_buffer (v9)"
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
(cherry picked from commit be5fc0d7f1)

BUG=b:77235812
TEST=emerge-eve arc-mesa

Change-Id: I0dde2e53eeb09af34d629b17d0692f0e00151fdf
Reviewed-on: https://chromium-review.googlesource.com/1133766
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Commit-Queue: Chad Versace <chadversary@chromium.org>
2018-07-12 18:13:03 +00:00
Chad Versace
09a9aafa81 UPSTREAM: anv/android: Fix Autotools build for VK_ANDROID_native_buffer
Changes to vk.xml and anv_entrypoints_gen.py broke the Autotools build
on Android. The changes undef'd the VK_ANDROID_native_buffer entrypoints
in anv_entrypoints.h.

Fix it with CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR.

CC: <mesa-stable@lists.freedesktop.org>
See-Also: 63525ba7 "android: enable VK_ANDROID_native_buffer"
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
(cherry picked from commit 8e403bc959)

BUG=b:77235812
TEST=none (because anv doesn't build yet)

Change-Id: Ic3b8dbeab7ee8663ca6dcca0401dc6340dddf832
Reviewed-on: https://chromium-review.googlesource.com/1133765
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Commit-Queue: Chad Versace <chadversary@chromium.org>
2018-07-12 18:13:02 +00:00
Stéphane Marchesin
d346f5b8bd CHROMIUM: st/mesa: Do not flush front buffer on context flush
Make gallium work again with new chrome.

BUG=none
TEST=compile

Signed-off-by: James Ausmus <james.ausmus@intel.com>
Signed-off-by: Prince Agyeman <prince.agyeman@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
(cherry picked from commit 8940a624ae)

BUG=b:77235812
TEST=emerge-grunt arc-mesa

Change-Id: I450f99e8e9c83a55626a28b80d5ed4ce884c8298
Reviewed-on: https://chromium-review.googlesource.com/1105701
Commit-Queue: Chad Versace <chadversary@chromium.org>
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
2018-07-12 18:13:02 +00:00
Chad Versace
ab8ac2c3e9 UPSTREAM: gallium: Fix automake for Android (v2)
Chromium OS uses Autotools and pkg-config when building Mesa for
Android. The gallium drivers were failing to find the headers and
libraries for zlib and Android's libbacktrace.

v2:
  - Don't add a check for zlib.pc. configure.ac already checks for
    zlib.pc elsewhere. [for tfiga]
  - Check for backtrace.pc separately from the other Android libs.
    [for tfiga]

Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit dc6665422a)

BUG=b:79872606
TEST=emerge-grunt arc-mesa
CQ-DEPEND=CL:1105634

Change-Id: If2e7fd953786723d6b7194f9174f5856a55c3b14
Reviewed-on: https://chromium-review.googlesource.com/1105700
Tested-by: Chad Versace <chadversary@chromium.org>
Commit-Queue: Chad Versace <chadversary@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
2018-07-12 18:13:00 +00:00
Tomasz Figa
d069832666 CHROMIUM: Add PRESUBMIT.cfg to disable various checks
This makes it so that we don't need to run 'repo upload --no-verify'.

BUG=b:26574868
TEST=ran upload on some CLs

Change-Id: I0b22a5ee0321dc454affeefcfac0eee75490bd6e
Reviewed-on: https://chromium-review.googlesource.com/780587
Tested-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Chad Versace <chadversary@chromium.org>
(cherry picked from commit 7cc5c96a9a)

BUG=b:77235812
TEST=none

Change-Id: Ia4285d3e178787874f439b76aaf8717f50fd7df2
Reviewed-on: https://chromium-review.googlesource.com/1105699
Reviewed-by: Bas Nieuwenhuizen <basni@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Commit-Queue: Ilja H. Friedel <ihf@chromium.org>
Tested-by: Ilja H. Friedel <ihf@chromium.org>
Trybot-Ready: Ilja H. Friedel <ihf@chromium.org>
2018-06-22 23:38:47 +00:00
38 changed files with 861 additions and 104 deletions

10
PRESUBMIT.cfg Normal file
View File

@@ -0,0 +1,10 @@
# This sample config file disables all of the ChromiumOS source style checks.
# Comment out the disable-flags for any checks you want to leave enabled.
[Hook Overrides]
stray_whitespace_check: false
long_line_check: false
cros_license_check: false
tab_check: false
bug_field_check: false
test_field_check: false

View File

@@ -1831,6 +1831,9 @@ for plat in $platforms; do
android)
PKG_CHECK_MODULES([ANDROID], [cutils hardware sync])
if test -n "$with_gallium_drivers"; then
PKG_CHECK_MODULES([BACKTRACE], [backtrace])
fi
DEFINES="$DEFINES -DHAVE_ANDROID_PLATFORM"
;;

View File

@@ -48,6 +48,7 @@ typedef unsigned int drm_drawable_t;
typedef struct drm_clip_rect drm_clip_rect_t;
#endif
#include <stdbool.h>
#include <stdint.h>
/**
@@ -746,7 +747,8 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS 46
#define __DRI_ATTRIB_YINVERTED 47
#define __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE 48
#define __DRI_ATTRIB_MAX (__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE + 1)
#define __DRI_ATTRIB_MUTABLE_RENDER_BUFFER 49 /* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR */
#define __DRI_ATTRIB_MAX 50
/* __DRI_ATTRIB_RENDER_TYPE */
#define __DRI_ATTRIB_RGBA_BIT 0x01
@@ -1888,9 +1890,57 @@ struct __DRI2rendererQueryExtensionRec {
* Image Loader extension. Drivers use this to allocate color buffers
*/
/**
* See __DRIimageLoaderExtensionRec::getBuffers::buffer_mask.
*/
enum __DRIimageBufferMask {
__DRI_IMAGE_BUFFER_BACK = (1 << 0),
__DRI_IMAGE_BUFFER_FRONT = (1 << 1)
__DRI_IMAGE_BUFFER_FRONT = (1 << 1),
/**
* A buffer shared between application and compositor. The buffer may be
* simultaneously accessed by each.
*
* A shared buffer is equivalent to an EGLSurface whose EGLConfig contains
* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR and whose active EGL_RENDER_BUFFER (as
* opposed to any pending, requested change to EGL_RENDER_BUFFER) is
* EGL_SINGLE_BUFFER.
*
* If buffer_mask contains __DRI_IMAGE_BUFFER_SHARED, then must contains no
* other bits. As a corollary, a __DRIdrawable that has a "shared" buffer
* has no front nor back buffer.
*
* The loader returns __DRI_IMAGE_BUFFER_SHARED in buffer_mask if and only
* if:
* - The loader supports __DRI_MUTABLE_RENDER_BUFFER_LOADER.
* - The driver supports __DRI_MUTABLE_RENDER_BUFFER_DRIVER.
* - The EGLConfig of the drawable EGLSurface contains
* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.
* - The EGLContext's EGL_RENDER_BUFFER is EGL_SINGLE_BUFFER.
* Equivalently, the EGLSurface's active EGL_RENDER_BUFFER (as
* opposed to any pending, requested change to EGL_RENDER_BUFFER) is
* EGL_SINGLE_BUFFER. (See the EGL 1.5 and
* EGL_KHR_mutable_render_buffer spec for details about "pending" vs
* "active" EGL_RENDER_BUFFER state).
*
* A shared buffer is similar to a front buffer in that all rendering to the
* buffer should appear promptly on the screen. It is different from
* a front buffer in that its behavior is independent from the
* GL_DRAW_BUFFER state. Specifically, if GL_DRAW_FRAMEBUFFER is 0 and the
* __DRIdrawable's buffer_mask is __DRI_IMAGE_BUFFER_SHARED, then all
* rendering should appear promptly on the screen if GL_DRAW_BUFFER is not
* GL_NONE.
*
* The difference between a shared buffer and a front buffer is motivated
* by the constraints of Android and OpenGL ES. OpenGL ES does not support
* front-buffer rendering. Android's SurfaceFlinger protocol provides the
* EGL driver only a back buffer and no front buffer. The shared buffer
* mode introduced by EGL_KHR_mutable_render_buffer is a backdoor though
* EGL that allows Android OpenGL ES applications to render to what is
* effectively the front buffer, a backdoor that required no change to the
* OpenGL ES API and little change to the SurfaceFlinger API.
*/
__DRI_IMAGE_BUFFER_SHARED = (1 << 2),
};
struct __DRIimageList {
@@ -1915,7 +1965,8 @@ struct __DRIimageLoaderExtensionRec {
* \param stamp Address of variable to be updated when
* getBuffers must be called again
* \param loaderPrivate The loaderPrivate for driDrawable
* \param buffer_mask Set of buffers to allocate
* \param buffer_mask Set of buffers to allocate. A bitmask of
* __DRIimageBufferMask.
* \param buffers Returned buffers
*/
int (*getBuffers)(__DRIdrawable *driDrawable,
@@ -2029,4 +2080,85 @@ struct __DRIbackgroundCallableExtensionRec {
GLboolean (*isThreadSafe)(void *loaderPrivate);
};
/**
* The driver portion of EGL_KHR_mutable_render_buffer.
*
* If the driver creates a __DRIconfig with
* __DRI_ATTRIB_MUTABLE_RENDER_BUFFER, then it must support this extension.
*
* To support this extension:
*
* - The driver should create at least one __DRIconfig with
* __DRI_ATTRIB_MUTABLE_RENDER_BUFFER. This is strongly recommended but
* not required.
*
* - The driver must be able to handle __DRI_IMAGE_BUFFER_SHARED if
* returned by __DRIimageLoaderExtension:getBuffers().
*
* - When rendering to __DRI_IMAGE_BUFFER_SHARED, it must call
* __DRImutableRenderBufferLoaderExtension::displaySharedBuffer() in
* response to glFlush and glFinish. (This requirement is not documented
* in EGL_KHR_mutable_render_buffer, but is a de-facto requirement in the
* Android ecosystem. Android applications expect that glFlush will
* immediately display the buffer when in shared buffer mode, and Android
* drivers comply with this expectation). It :may: call
* displaySharedBuffer() more often than required.
*
* - When rendering to __DRI_IMAGE_BUFFER_SHARED, it must ensure that the
* buffer is always in a format compatible for display because the
* display engine (usually SurfaceFlinger or hwcomposer) may display the
* image at any time, even concurrently with 3D rendering. For example,
* display hardware and the GL hardware may be able to access the buffer
* simultaneously. In particular, if the buffer is compressed then take
* care that SurfaceFlinger and hwcomposer can consume the compression
* format.
*
* \see __DRI_IMAGE_BUFFER_SHARED
* \see __DRI_ATTRIB_MUTABLE_RENDER_BUFFER
* \see __DRI_MUTABLE_RENDER_BUFFER_LOADER
*/
#define __DRI_MUTABLE_RENDER_BUFFER_DRIVER "DRI_MutableRenderBufferDriver"
#define __DRI_MUTABLE_RENDER_BUFFER_DRIVER_VERSION 1
typedef struct __DRImutableRenderBufferDriverExtensionRec __DRImutableRenderBufferDriverExtension;
struct __DRImutableRenderBufferDriverExtensionRec {
__DRIextension base;
};
/**
* The loader portion of EGL_KHR_mutable_render_buffer.
*
* Requires loader extension DRI_IMAGE_LOADER, through which the loader sends
* __DRI_IMAGE_BUFFER_SHARED to the driver.
*
* \see __DRI_MUTABLE_RENDER_BUFFER_DRIVER
*/
#define __DRI_MUTABLE_RENDER_BUFFER_LOADER "DRI_MutableRenderBufferLoader"
#define __DRI_MUTABLE_RENDER_BUFFER_LOADER_VERSION 1
typedef struct __DRImutableRenderBufferLoaderExtensionRec __DRImutableRenderBufferLoaderExtension;
struct __DRImutableRenderBufferLoaderExtensionRec {
__DRIextension base;
/**
* Inform the display engine (that is, SurfaceFlinger and/or hwcomposer)
* that the __DRIdrawable has new content.
*
* The display engine may ignore this call, for example, if it continually
* refreshes and displays the buffer on every frame, as in
* EGL_ANDROID_front_buffer_auto_refresh. On the other extreme, the display
* engine may refresh and display the buffer only in frames in which the
* driver calls this.
*
* If the fence_fd is not -1, then the display engine will display the
* buffer only after the fence signals.
*
* The drawable's current __DRIimageBufferMask, as returned by
* __DRIimageLoaderExtension::getBuffers(), must be
* __DRI_IMAGE_BUFFER_SHARED.
*/
void (*displaySharedBuffer)(__DRIdrawable *drawable, int fence_fd,
void *loaderPrivate);
};
#endif

View File

@@ -224,10 +224,12 @@ expanded_line:
glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro);
_glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2.value);
}
| LINE_EXPANDED integer_constant NEWLINE {
| LINE_EXPANDED expression NEWLINE {
if (parser->is_gles && $2.undefined_macro)
glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro);
parser->has_new_line_number = 1;
parser->new_line_number = $2;
_mesa_string_buffer_printf(parser->output, "#line %" PRIiMAX "\n", $2);
parser->new_line_number = $2.value;
_mesa_string_buffer_printf(parser->output, "#line %" PRIiMAX "\n", $2.value);
}
| LINE_EXPANDED integer_constant integer_constant NEWLINE {
parser->has_new_line_number = 1;
@@ -238,6 +240,19 @@ expanded_line:
"#line %" PRIiMAX " %" PRIiMAX "\n",
$2, $3);
}
| LINE_EXPANDED '(' expression ')' '(' expression ')' NEWLINE {
if (parser->is_gles && $3.undefined_macro)
glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $3.undefined_macro);
if (parser->is_gles && $6.undefined_macro)
glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $6.undefined_macro);
parser->has_new_line_number = 1;
parser->new_line_number = $3.value;
parser->has_new_source_number = 1;
parser->new_source_number = $6.value;
_mesa_string_buffer_printf(parser->output,
"#line %" PRIiMAX " %" PRIiMAX "\n",
$3.value, $6.value);
}
;
define:

View File

@@ -671,6 +671,9 @@ private:
this->record_next_sampler))
return;
/* Avoid overflowing the sampler array. (crbug.com/141901) */
this->next_sampler = MIN2(this->next_sampler, MAX_SAMPLERS);
for (unsigned i = uniform->opaque[shader_type].index;
i < MIN2(this->next_sampler, MAX_SAMPLERS);
i++) {

View File

@@ -41,6 +41,7 @@ LOCAL_SRC_FILES := \
LOCAL_CFLAGS := \
-D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_ANDROID \
-D_EGL_BUILT_IN_DRIVER_DRI2 \
-DHAS_GRALLOC_DRM_HEADERS \
-DHAVE_ANDROID_PLATFORM
LOCAL_C_INCLUDES := \

View File

@@ -108,7 +108,9 @@ endif
if HAVE_PLATFORM_ANDROID
AM_CFLAGS += $(ANDROID_CFLAGS)
libEGL_common_la_LIBADD += $(ANDROID_LIBS)
dri2_backend_FILES += drivers/dri2/platform_android.c
dri2_backend_FILES += \
drivers/dri2/platform_android.c \
drivers/dri2/egl_dri2_drm_gralloc.h
endif
AM_CFLAGS += \

View File

@@ -300,7 +300,10 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
_eglSetConfigKey(&base, EGL_MAX_PBUFFER_HEIGHT,
_EGL_MAX_PBUFFER_HEIGHT);
break;
case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER:
if (disp->Extensions.KHR_mutable_render_buffer)
surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
break;
default:
key = dri2_to_egl_attribute_map[attrib];
if (key != 0)
@@ -460,6 +463,7 @@ static const struct dri2_extension_match optional_core_extensions[] = {
{ __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) },
{ __DRI2_FLUSH_CONTROL, 1, offsetof(struct dri2_egl_display, flush_control) },
{ __DRI2_BLOB, 1, offsetof(struct dri2_egl_display, blob) },
{ __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1, offsetof(struct dri2_egl_display, mutable_render_buffer) },
{ NULL, 0, 0 }
};
@@ -1317,12 +1321,6 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
dri_config = dri2_config->dri_config[1][0];
else
dri_config = dri2_config->dri_config[0][0];
/* EGL_WINDOW_BIT is set only when there is a double-buffered dri_config.
* This makes sure the back buffer will always be used.
*/
if (conf->SurfaceType & EGL_WINDOW_BIT)
dri2_ctx->base.WindowRenderBuffer = EGL_BACK_BUFFER;
}
else
dri_config = NULL;
@@ -1493,6 +1491,8 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
_EGLDisplay *old_disp = NULL;
struct dri2_egl_display *old_dri2_dpy = NULL;
_EGLContext *old_ctx;
_EGLSurface *old_dsurf, *old_rsurf;
_EGLSurface *tmp_dsurf, *tmp_rsurf;
@@ -1509,6 +1509,11 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
return EGL_FALSE;
}
if (old_ctx) {
old_disp = old_ctx->Resource.Display;
old_dri2_dpy = dri2_egl_display(old_disp);
}
/* flush before context switch */
if (old_ctx)
dri2_gl_flush();
@@ -1522,31 +1527,30 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
if (old_dsurf)
dri2_surf_update_fence_fd(old_ctx, disp, old_dsurf);
/* Disable shared buffer mode */
if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) &&
old_dri2_dpy->vtbl->set_shared_buffer_mode) {
old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, false);
}
dri2_dpy->core->unbindContext(old_cctx);
}
unbind = (cctx == NULL && ddraw == NULL && rdraw == NULL);
if (unbind || dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) {
dri2_destroy_surface(drv, disp, old_dsurf);
dri2_destroy_surface(drv, disp, old_rsurf);
if (!unbind)
dri2_dpy->ref_count++;
if (old_ctx) {
EGLDisplay old_disp = _eglGetDisplayHandle(old_ctx->Resource.Display);
dri2_destroy_context(drv, disp, old_ctx);
dri2_display_release(old_disp);
}
return EGL_TRUE;
} else {
if (!unbind && !dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) {
/* undo the previous _eglBindContext */
_eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &tmp_dsurf, &tmp_rsurf);
assert(&dri2_ctx->base == ctx &&
tmp_dsurf == dsurf &&
tmp_rsurf == rsurf);
if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) &&
old_dri2_dpy->vtbl->set_shared_buffer_mode) {
old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, true);
}
_eglPutSurface(dsurf);
_eglPutSurface(rsurf);
_eglPutContext(ctx);
@@ -1561,6 +1565,31 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
*/
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
}
dri2_destroy_surface(drv, disp, old_dsurf);
dri2_destroy_surface(drv, disp, old_rsurf);
if (!unbind)
dri2_dpy->ref_count++;
if (old_ctx) {
dri2_destroy_context(drv, disp, old_ctx);
dri2_display_release(old_disp);
}
if (dsurf && _eglSurfaceHasMutableRenderBuffer(dsurf) &&
dri2_dpy->vtbl->set_shared_buffer_mode) {
/* Always update the shared buffer mode. This is obviously needed when
* the active EGL_RENDER_BUFFER is EGL_SINGLE_BUFFER. When
* EGL_RENDER_BUFFER is EGL_BACK_BUFFER, the update protects us in the
* case where external non-EGL API may have changed window's shared
* buffer mode since we last saw it.
*/
bool mode = (dsurf->ActiveRenderBuffer == EGL_SINGLE_BUFFER);
dri2_dpy->vtbl->set_shared_buffer_mode(disp, dsurf, mode);
}
return EGL_TRUE;
}
__DRIdrawable *

View File

@@ -67,7 +67,7 @@ struct zwp_linux_dmabuf_v1;
#include <system/window.h>
#include <hardware/gralloc.h>
#include <gralloc_drm_handle.h>
#include "platform_android_gralloc_drm.h"
#endif /* HAVE_ANDROID_PLATFORM */
@@ -153,6 +153,12 @@ struct dri2_egl_display_vtbl {
__DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf);
void (*close_screen_notify)(_EGLDisplay *dpy);
/* Used in EGL_KHR_mutable_render_buffer to update the native window's
* shared buffer mode.
*/
bool (*set_shared_buffer_mode)(_EGLDisplay *dpy, _EGLSurface *surf,
bool mode);
};
struct dri2_egl_display
@@ -180,6 +186,7 @@ struct dri2_egl_display
const __DRI2blobExtension *blob;
const __DRI2rendererQueryExtension *rendererQuery;
const __DRI2interopExtension *interop;
const __DRImutableRenderBufferDriverExtension *mutable_render_buffer;
int fd;
/* dri2_initialize/dri2_terminate increment/decrement this count, so does

View File

@@ -37,7 +37,7 @@
#include "loader.h"
#include "egl_dri2.h"
#include "egl_dri2_fallbacks.h"
#include "gralloc_drm.h"
#include "platform_android_gralloc_drm.h"
#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
@@ -293,6 +293,32 @@ droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf)
}
}
static bool
droid_set_shared_buffer_mode(_EGLDisplay *disp, _EGLSurface *surf, bool mode)
{
#if ANDROID_API_LEVEL >= 24
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct ANativeWindow *window = dri2_surf->window;
assert(surf->Type == EGL_WINDOW_BIT);
assert(_eglSurfaceHasMutableRenderBuffer(&dri2_surf->base));
_eglLog(_EGL_DEBUG, "%s: mode=%d", __func__, mode);
if (native_window_set_shared_buffer_mode(window, mode)) {
_eglLog(_EGL_WARNING, "failed native_window_set_shared_buffer_mode"
"(window=%p, mode=%d)", window, mode);
return false;
}
return true;
#else
_eglLog(_EGL_FATAL, "%s:%d: internal error: unreachable", __FILE__, __LINE__);
return false;
#endif
}
static _EGLSurface *
droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
_EGLConfig *conf, void *native_window,
@@ -583,6 +609,21 @@ droid_image_get_buffers(__DRIdrawable *driDrawable,
if (update_buffers(dri2_surf) < 0)
return 0;
if (_eglSurfaceInSharedBufferMode(&dri2_surf->base)) {
if (get_back_bo(dri2_surf) < 0)
return 0;
/* We have dri_image_back because this is a window surface and
* get_back_bo() succeeded.
*/
assert(dri2_surf->dri_image_back);
images->back = dri2_surf->dri_image_back;
images->image_mask |= __DRI_IMAGE_BUFFER_SHARED;
/* There exists no accompanying back nor front buffer. */
return 1;
}
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
if (get_front_bo(dri2_surf, format) < 0)
return 0;
@@ -629,6 +670,21 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
if (dri2_surf->base.Type != EGL_WINDOW_BIT)
return EGL_TRUE;
const bool has_mutable_rb = _eglSurfaceHasMutableRenderBuffer(draw);
/* From the EGL_KHR_mutable_render_buffer spec (v12):
*
* If surface is a single-buffered window, pixmap, or pbuffer surface
* for which there is no pending change to the EGL_RENDER_BUFFER
* attribute, eglSwapBuffers has no effect.
*/
if (has_mutable_rb &&
draw->RequestedRenderBuffer == EGL_SINGLE_BUFFER &&
draw->ActiveRenderBuffer == EGL_SINGLE_BUFFER) {
_eglLog(_EGL_DEBUG, "%s: remain in shared buffer mode", __func__);
return EGL_TRUE;
}
for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (dri2_surf->color_buffers[i].age > 0)
dri2_surf->color_buffers[i].age++;
@@ -653,6 +709,18 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
/* Update the shared buffer mode */
if (has_mutable_rb &&
draw->ActiveRenderBuffer != draw->RequestedRenderBuffer) {
bool mode = (draw->RequestedRenderBuffer == EGL_SINGLE_BUFFER);
_eglLog(_EGL_DEBUG, "%s: change to shared buffer mode %d",
__func__, mode);
if (!droid_set_shared_buffer_mode(disp, draw, mode))
return EGL_FALSE;
draw->ActiveRenderBuffer = draw->RequestedRenderBuffer;
}
return EGL_TRUE;
}
@@ -1058,7 +1126,6 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
{ HAL_PIXEL_FORMAT_RGBA_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 } },
{ HAL_PIXEL_FORMAT_RGBX_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 } },
{ HAL_PIXEL_FORMAT_RGB_565, { 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 } },
{ HAL_PIXEL_FORMAT_BGRA_8888, { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 } },
};
unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
@@ -1126,7 +1193,7 @@ droid_open_device(struct dri2_egl_display *dri2_dpy)
GRALLOC_MODULE_PERFORM_GET_DRM_FD,
&fd);
if (err || fd < 0) {
_eglLog(_EGL_WARNING, "fail to get drm fd");
_eglLog(_EGL_DEBUG, "fail to get drm fd");
fd = -1;
}
@@ -1156,6 +1223,7 @@ static const struct dri2_egl_display_vtbl droid_display_vtbl = {
.create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
.set_shared_buffer_mode = droid_set_shared_buffer_mode,
};
static const __DRIdri2LoaderExtension droid_dri2_loader_extension = {
@@ -1175,10 +1243,89 @@ static const __DRIimageLoaderExtension droid_image_loader_extension = {
.getCapability = droid_get_capability,
};
static void
droid_display_shared_buffer(__DRIdrawable *driDrawable, int fence_fd,
void *loaderPrivate)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct ANativeWindowBuffer *old_buffer UNUSED = dri2_surf->buffer;
if (!_eglSurfaceInSharedBufferMode(&dri2_surf->base)) {
_eglLog(_EGL_WARNING, "%s: internal error: buffer is not shared",
__func__);
return;
}
if (fence_fd >= 0) {
/* The driver's fence is more recent than the surface's out fence, if it
* exists at all. So use the driver's fence.
*/
if (dri2_surf->out_fence_fd >= 0) {
close(dri2_surf->out_fence_fd);
dri2_surf->out_fence_fd = -1;
}
} else if (dri2_surf->out_fence_fd >= 0) {
fence_fd = dri2_surf->out_fence_fd;
dri2_surf->out_fence_fd = -1;
}
if (dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer,
fence_fd)) {
_eglLog(_EGL_WARNING, "%s: ANativeWindow::queueBuffer failed", __func__);
close(fence_fd);
return;
}
fence_fd = -1;
if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer,
&fence_fd)) {
/* Tear down the surface because it no longer has a back buffer. */
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
_eglLog(_EGL_WARNING, "%s: ANativeWindow::dequeueBuffer failed", __func__);
dri2_surf->base.Lost = true;
dri2_surf->buffer = NULL;
dri2_surf->back = NULL;
if (dri2_surf->dri_image_back) {
dri2_dpy->image->destroyImage(dri2_surf->dri_image_back);
dri2_surf->dri_image_back = NULL;
}
dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
return;
}
if (fence_fd < 0)
return;
/* Access to the buffer is controlled by a sync fence. Block on it.
*
* Ideally, we would submit the fence to the driver, and the driver would
* postpone command execution until it signalled. But DRI lacks API for
* that (as of 2018-04-11).
*
* SYNC_IOC_WAIT waits forever if timeout < 0
*/
sync_wait(fence_fd, -1);
close(fence_fd);
}
static const __DRImutableRenderBufferLoaderExtension droid_mutable_render_buffer_extension = {
.base = { __DRI_MUTABLE_RENDER_BUFFER_LOADER, 1 },
.displaySharedBuffer = droid_display_shared_buffer,
};
static const __DRIextension *droid_dri2_loader_extensions[] = {
&droid_dri2_loader_extension.base,
&image_lookup_extension.base,
&use_invalidate.base,
/* No __DRI_MUTABLE_RENDER_BUFFER_LOADER because it requires
* __DRI_IMAGE_LOADER.
*/
NULL,
};
@@ -1186,9 +1333,82 @@ static const __DRIextension *droid_image_loader_extensions[] = {
&droid_image_loader_extension.base,
&image_lookup_extension.base,
&use_invalidate.base,
&droid_mutable_render_buffer_extension.base,
NULL,
};
static bool
droid_probe_device(_EGLDisplay *dpy)
{
struct dri2_egl_display *dri2_dpy = dpy->DriverData;
bool loaded;
dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
if (!dri2_dpy->is_render_node && !gralloc_supports_gem_names()) {
_eglLog(_EGL_WARNING, "DRI2: control nodes not supported without GEM name suport in gralloc\n");
return false;
}
if (dpy->Options.ForceSoftware)
dri2_dpy->driver_name = strdup("kms_swrast");
else
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (dri2_dpy->driver_name == NULL) {
_eglLog(_EGL_WARNING, "DRI2: failed to get driver name");
return false;
}
/* render nodes cannot use Gem names, and thus do not support
* the __DRI_DRI2_LOADER extension */
if (!dri2_dpy->is_render_node) {
dri2_dpy->loader_extensions = droid_dri2_loader_extensions;
loaded = dri2_load_driver(dpy);
} else {
dri2_dpy->loader_extensions = droid_image_loader_extensions;
loaded = dri2_load_driver_dri3(dpy);
}
if (!loaded) {
_eglLog(_EGL_WARNING, "DRI2: failed to load driver");
free(dri2_dpy->driver_name);
dri2_dpy->driver_name = NULL;
return false;
}
return true;
}
static bool
droid_probe_devices(_EGLDisplay *dpy)
{
struct dri2_egl_display *dri2_dpy = dpy->DriverData;
const char *name_template = "%s/renderD%d";
const int base = 128;
const int limit = 64;
int minor;
for (minor = base; minor < base + limit; ++minor) {
char *card_path;
if (asprintf(&card_path, name_template, DRM_DIR_NAME, minor) < 0)
continue;
dri2_dpy->fd = loader_open_device(card_path);
free(card_path);
if (dri2_dpy->fd < 0)
continue;
if (droid_probe_device(dpy))
return true;
close(dri2_dpy->fd);
dri2_dpy->fd = -1;
}
return false;
}
EGLBoolean
dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
{
@@ -1196,10 +1416,6 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
const char *err;
int ret;
/* Not supported yet */
if (disp->Options.ForceSoftware)
return EGL_FALSE;
loader_set_logger(_eglLog);
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
@@ -1217,35 +1433,16 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
disp->DriverData = (void *) dri2_dpy;
dri2_dpy->fd = droid_open_device(dri2_dpy);
if (dri2_dpy->fd < 0) {
err = "DRI2: failed to open device";
if (dri2_dpy->fd >= 0 && !droid_probe_device(disp)) {
_eglLog(_EGL_WARNING, "DRI2: Failed to load %s driver",
disp->Options.ForceSoftware ? "software" : "hardware");
goto cleanup;
}
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (dri2_dpy->driver_name == NULL) {
err = "DRI2: failed to get driver name";
} else if (!droid_probe_devices(disp)) {
_eglLog(_EGL_WARNING, "DRI2: Failed to load %s driver",
disp->Options.ForceSoftware ? "software" : "hardware");
goto cleanup;
}
dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
/* render nodes cannot use Gem names, and thus do not support
* the __DRI_DRI2_LOADER extension */
if (!dri2_dpy->is_render_node) {
dri2_dpy->loader_extensions = droid_dri2_loader_extensions;
if (!dri2_load_driver(disp)) {
err = "DRI2: failed to load driver";
goto cleanup;
}
} else {
dri2_dpy->loader_extensions = droid_image_loader_extensions;
if (!dri2_load_driver_dri3(disp)) {
err = "DRI3: failed to load driver";
goto cleanup;
}
}
if (!dri2_create_screen(disp)) {
err = "DRI2: failed to create screen";
goto cleanup;
@@ -1264,11 +1461,6 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
*/
dri2_setup_swap_interval(disp, 1);
if (!droid_add_configs_for_visuals(drv, disp)) {
err = "DRI2: failed to add configs";
goto cleanup;
}
disp->Extensions.ANDROID_framebuffer_target = EGL_TRUE;
disp->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
disp->Extensions.ANDROID_recordable = EGL_TRUE;
@@ -1277,6 +1469,20 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.KHR_partial_update = EGL_TRUE;
#endif
disp->Extensions.KHR_image = EGL_TRUE;
#if ANDROID_API_LEVEL >= 24
if (dri2_dpy->mutable_render_buffer &&
dri2_dpy->loader_extensions == droid_image_loader_extensions) {
disp->Extensions.KHR_mutable_render_buffer = EGL_TRUE;
}
#endif
/* Create configs *after* enabling extensions because presence of DRI
* driver extensions can affect the capabilities of EGLConfigs.
*/
if (!droid_add_configs_for_visuals(drv, disp)) {
err = "DRI2: failed to add configs";
goto cleanup;
}
/* Fill vtbl last to prevent accidentally calling virtual function during
* initialization.

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#pragma once
#ifdef HAS_GRALLOC_DRM_HEADERS
#include <gralloc_drm.h>
#include <gralloc_drm_handle.h>
static inline bool gralloc_supports_gem_names(void) { return true; }
#else
#define GRALLOC_MODULE_PERFORM_GET_DRM_FD 0x0FD4DEAD
static inline int gralloc_drm_get_gem_handle(buffer_handle_t handle)
{
return 0; /* Not supported, return invalid handle. */
}
static inline bool gralloc_supports_gem_names(void) { return false; }
#endif

View File

@@ -509,6 +509,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(KHR_image);
_EGL_CHECK_EXTENSION(KHR_image_base);
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
_EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
_EGL_CHECK_EXTENSION(KHR_no_config_context);
_EGL_CHECK_EXTENSION(KHR_partial_update);
_EGL_CHECK_EXTENSION(KHR_reusable_sync);

View File

@@ -272,6 +272,7 @@ static const struct {
EGLBoolean
_eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
{
_EGLDisplay *disp = conf->Display;
EGLint i, attr, val;
EGLBoolean valid = EGL_TRUE;
@@ -340,6 +341,8 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
EGL_VG_ALPHA_FORMAT_PRE_BIT |
EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
if (disp->Extensions.KHR_mutable_render_buffer)
mask |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
break;
case EGL_RENDERABLE_TYPE:
case EGL_CONFORMANT:

View File

@@ -588,7 +588,6 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
_eglInitResource(&ctx->Resource, sizeof(*ctx), dpy);
ctx->ClientAPI = api;
ctx->Config = conf;
ctx->WindowRenderBuffer = EGL_NONE;
ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
ctx->ClientMajorVersion = 1; /* the default, per EGL spec */
@@ -620,15 +619,42 @@ static EGLint
_eglQueryContextRenderBuffer(_EGLContext *ctx)
{
_EGLSurface *surf = ctx->DrawSurface;
EGLint rb;
/* From the EGL 1.5 spec:
*
* - If the context is not bound to a surface, then EGL_NONE will be
* returned.
*/
if (!surf)
return EGL_NONE;
if (surf->Type == EGL_WINDOW_BIT && ctx->WindowRenderBuffer != EGL_NONE)
rb = ctx->WindowRenderBuffer;
else
rb = surf->RenderBuffer;
return rb;
switch (surf->Type) {
default:
unreachable("bad EGLSurface type");
case EGL_PIXMAP_BIT:
/* - If the context is bound to a pixmap surface, then EGL_SINGLE_BUFFER
* will be returned.
*/
return EGL_SINGLE_BUFFER;
case EGL_PBUFFER_BIT:
/* - If the context is bound to a pbuffer surface, then EGL_BACK_BUFFER
* will be returned.
*/
return EGL_BACK_BUFFER;
case EGL_WINDOW_BIT:
/* - If the context is bound to a window surface, then either
* EGL_BACK_BUFFER or EGL_SINGLE_BUFFER may be returned. The value
* returned depends on both the buffer requested by the setting of the
* EGL_RENDER_BUFFER property of the surface [...], and on the client
* API (not all client APIs support single-buffer Rendering to window
* surfaces). Some client APIs allow control of whether rendering goes
* to the front or back buffer. This client API-specific choice is not
* reflected in the returned value, which only describes the buffer
* that will be rendered to by default if not overridden by the client
* API.
*/
return surf->ActiveRenderBuffer;
}
}

View File

@@ -65,9 +65,6 @@ struct _egl_context
EGLint ContextPriority;
EGLBoolean NoError;
EGLint ReleaseBehavior;
/* The real render buffer when a window surface is bound */
EGLint WindowRenderBuffer;
};

View File

@@ -127,6 +127,7 @@ struct _egl_extensions
EGLBoolean KHR_image;
EGLBoolean KHR_image_base;
EGLBoolean KHR_image_pixmap;
EGLBoolean KHR_mutable_render_buffer;
EGLBoolean KHR_no_config_context;
EGLBoolean KHR_partial_update;
EGLBoolean KHR_reusable_sync;

View File

@@ -122,7 +122,13 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->RenderBuffer = val;
surf->RequestedRenderBuffer = val;
if (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) {
/* Unlike normal EGLSurfaces, one with a mutable render buffer
* uses the application-chosen render buffer.
*/
surf->ActiveRenderBuffer = val;
}
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
if (!dpy->Extensions.NV_post_sub_buffer ||
@@ -285,7 +291,8 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
surf->TextureTarget = EGL_NO_TEXTURE;
surf->MipmapTexture = EGL_FALSE;
surf->LargestPbuffer = EGL_FALSE;
surf->RenderBuffer = renderBuffer;
surf->RequestedRenderBuffer = renderBuffer;
surf->ActiveRenderBuffer = renderBuffer;
surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
@@ -358,7 +365,35 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
*value = surface->SwapBehavior;
break;
case EGL_RENDER_BUFFER:
*value = surface->RenderBuffer;
/* From the EGL_KHR_mutable_render_buffer spec (v12):
*
* Querying EGL_RENDER_BUFFER returns the buffer which client API
* rendering is requested to use. For a window surface, this is the
* attribute value specified when the surface was created or last set
* via eglSurfaceAttrib.
*
* In other words, querying a window surface returns the value most
* recently *requested* by the user.
*
* The paragraph continues in the EGL 1.5 spec (2014.08.27):
*
* For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
* surface, it is always EGL_SINGLE_BUFFER . To determine the actual
* buffer being rendered to by a context, call eglQueryContext.
*/
switch (surface->Type) {
default:
unreachable("bad EGLSurface type");
case EGL_WINDOW_BIT:
*value = surface->RequestedRenderBuffer;
break;
case EGL_PBUFFER_BIT:
*value = EGL_BACK_BUFFER;
break;
case EGL_PIXMAP_BIT:
*value = EGL_SINGLE_BUFFER;
break;
}
break;
case EGL_PIXEL_ASPECT_RATIO:
*value = surface->AspectRatio;
@@ -450,6 +485,31 @@ _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
break;
surface->MultisampleResolve = value;
break;
case EGL_RENDER_BUFFER:
if (!dpy->Extensions.KHR_mutable_render_buffer) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) {
err = EGL_BAD_PARAMETER;
break;
}
/* From the EGL_KHR_mutable_render_buffer spec (v12):
*
* If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE
* attribute of the EGLConfig used to create surface does not contain
* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is
* generated [...].
*/
if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) {
err = EGL_BAD_MATCH;
break;
}
surface->RequestedRenderBuffer = value;
break;
case EGL_SWAP_BEHAVIOR:
switch (value) {
case EGL_BUFFER_DESTROYED:
@@ -551,3 +611,18 @@ _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
{
return EGL_TRUE;
}
EGLBoolean
_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf)
{
return surf->Type == EGL_WINDOW_BIT &&
surf->Config &&
(surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR);
}
EGLBoolean
_eglSurfaceInSharedBufferMode(_EGLSurface *surf)
{
return _eglSurfaceHasMutableRenderBuffer(surf) &&
surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER;
}

View File

@@ -67,7 +67,59 @@ struct _egl_surface
EGLenum TextureTarget;
EGLBoolean MipmapTexture;
EGLBoolean LargestPbuffer;
EGLenum RenderBuffer;
/**
* Value of EGL_RENDER_BUFFER selected at creation.
*
* The user may select, for window surfaces, the EGL_RENDER_BUFFER through
* the attribute list of eglCreateWindowSurface(). The EGL spec allows the
* implementation to ignore request, though; hence why we maintain both
* RequestedRenderBuffer and ActiveRenderBuffer. For pbuffer and pixmap
* surfaces, the EGL spec hard-codes the EGL_RENDER_BUFFER value and the
* user must not provide it in the attribute list.
*
* Normally, the attribute is immutable and after surface creation.
* However, EGL_KHR_mutable_render_buffer allows the user to change it in
* window surfaces via eglSurfaceAttrib, in which case
* eglQuerySurface(EGL_RENDER_BUFFER) will immediately afterwards return
* the requested value but the actual render buffer used by the context
* does not change until completion of the next eglSwapBuffers call.
*
* From the EGL_KHR_mutable_render_buffer spec (v12):
*
* Querying EGL_RENDER_BUFFER returns the buffer which client API
* rendering is requested to use. For a window surface, this is the
* attribute value specified when the surface was created or last set
* via eglSurfaceAttrib.
*
* eglQueryContext(EGL_RENDER_BUFFER) ignores this.
*/
EGLenum RequestedRenderBuffer;
/**
* The EGL_RENDER_BUFFER in use by the context.
*
* This is valid only when bound as the draw surface. This may differ from
* the RequestedRenderBuffer.
*
* Refer to eglQueryContext(EGL_RENDER_BUFFER) in the EGL spec.
* eglQuerySurface(EGL_RENDER_BUFFER) ignores this.
*
* If a window surface is bound as the draw surface and has a pending,
* user-requested change to EGL_RENDER_BUFFER, then the next eglSwapBuffers
* will flush the pending change. (The flush of EGL_RENDER_BUFFER state may
* occur without the implicit glFlush induced by eglSwapBuffers). The spec
* requires that the flush occur at that time and nowhere else. During the
* state-flush, we copy RequestedRenderBuffer to ActiveRenderBuffer.
*
* From the EGL_KHR_mutable_render_buffer spec (v12):
*
* If [...] there is a pending change to the EGL_RENDER_BUFFER
* attribute, eglSwapBuffers performs an implicit flush operation on the
* context and effects the attribute change.
*/
EGLenum ActiveRenderBuffer;
EGLenum VGAlphaFormat;
EGLenum VGColorspace;
EGLenum GLColorspace;
@@ -124,6 +176,11 @@ _eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLin
extern EGLBoolean
_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval);
extern EGLBoolean
_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf);
extern EGLBoolean
_eglSurfaceInSharedBufferMode(_EGLSurface *surf);
/**
* Increment reference count for the surface.

View File

@@ -59,6 +59,12 @@ GALLIUM_COMMON_LIB_DEPS += \
$(LIBDRM_LIBS)
endif
if HAVE_PLATFORM_ANDROID
GALLIUM_COMMON_LIB_DEPS += \
$(ANDROID_LIBS) \
$(BACKTRACE_LIBS)
endif
GALLIUM_WINSYS_CFLAGS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/include \

View File

@@ -13,6 +13,7 @@ AM_CFLAGS = \
$(MSVC2013_COMPAT_CFLAGS)
AM_CXXFLAGS = \
$(GALLIUM_CFLAGS) \
$(VISIBILITY_CXXFLAGS) \
$(MSVC2013_COMPAT_CXXFLAGS)
@@ -21,6 +22,14 @@ libgallium_la_SOURCES = \
$(NIR_SOURCES) \
$(GENERATED_SOURCES)
if HAVE_PLATFORM_ANDROID
# Android's libbacktrace headers required C++11, but the Android toolchain (at
# least in the Chrome OS SDK) does not enable C++11 by default.
AM_CXXFLAGS += $(CXX11_CXXFLAGS)
libgallium_la_SOURCES += util/u_debug_stack_android.cpp
endif
if HAVE_LIBDRM
AM_CFLAGS += \
@@ -37,7 +46,6 @@ AM_CFLAGS += \
$(LLVM_CFLAGS)
AM_CXXFLAGS += \
$(GALLIUM_CFLAGS) \
$(LLVM_CXXFLAGS)
libgallium_la_SOURCES += \

View File

@@ -528,7 +528,7 @@ int virgl_encoder_inline_write(struct virgl_context *ctx,
left_bytes = size;
while (left_bytes) {
if (ctx->cbuf->cdw + 12 > VIRGL_MAX_CMDBUF_DWORDS)
if (ctx->cbuf->cdw + 12 >= VIRGL_MAX_CMDBUF_DWORDS)
ctx->base.flush(&ctx->base, NULL, 0);
thispass = (VIRGL_MAX_CMDBUF_DWORDS - ctx->cbuf->cdw - 12) * 4;

View File

@@ -274,7 +274,7 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes, 1,
GL_TRUE, !mixed_color_depth);
GL_TRUE, !mixed_color_depth, GL_FALSE);
configs = driConcatConfigs(configs, new_configs);
/* Multi-sample configs without an accumulation buffer. */
@@ -284,7 +284,7 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes+1, num_msaa_modes-1,
GL_FALSE, !mixed_color_depth);
GL_FALSE, !mixed_color_depth, GL_FALSE);
configs = driConcatConfigs(configs, new_configs);
}
}

View File

@@ -26,8 +26,10 @@
*
**************************************************************************/
#if !defined(ANDROID) || ANDROID_API_LEVEL >= 26
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
@@ -83,6 +85,7 @@ dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
return TRUE;
}
#if !defined(ANDROID) || ANDROID_API_LEVEL >= 26
static char *
alloc_shm(struct dri_sw_displaytarget *dri_sw_dt, unsigned size)
{
@@ -101,6 +104,7 @@ alloc_shm(struct dri_sw_displaytarget *dri_sw_dt, unsigned size)
return addr;
}
#endif
static struct sw_displaytarget *
dri_sw_displaytarget_create(struct sw_winsys *winsys,
@@ -131,8 +135,11 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
size = dri_sw_dt->stride * nblocksy;
dri_sw_dt->shmid = -1;
#if !defined(ANDROID) || ANDROID_API_LEVEL >= 26
if (ws->lf->put_image_shm)
dri_sw_dt->data = alloc_shm(dri_sw_dt, size);
#endif
if(!dri_sw_dt->data)
dri_sw_dt->data = align_malloc(size, alignment);
@@ -156,8 +163,10 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws,
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
if (dri_sw_dt->shmid >= 0) {
#if !defined(ANDROID) || ANDROID_API_LEVEL >= 26
shmdt(dri_sw_dt->data);
shmctl(dri_sw_dt->shmid, IPC_RMID, 0);
#endif
} else {
align_free(dri_sw_dt->data);
}

View File

@@ -164,7 +164,10 @@ VULKAN_LIB_DEPS = \
-lm
if HAVE_PLATFORM_ANDROID
VULKAN_CPPFLAGS += $(ANDROID_CPPFLAGS)
VULKAN_CPPFLAGS += \
$(ANDROID_CPPFLAGS) \
-DVK_USE_PLATFORM_ANDROID_KHR
VULKAN_CFLAGS += $(ANDROID_CFLAGS)
VULKAN_LIB_DEPS += $(ANDROID_LIBS)
VULKAN_SOURCES += $(VULKAN_ANDROID_FILES)

View File

@@ -180,7 +180,7 @@ anv_image_from_gralloc(VkDevice device_h,
goto fail_create;
if (bo->size < image->size) {
result = vk_errorf(device, device->instance,
result = vk_errorf(device->instance, device,
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR,
"dma-buf from VkNativeBufferANDROID is too small for "
"VkImage: %"PRIu64"B < %"PRIu64"B",

View File

@@ -81,6 +81,8 @@ setupLoaderExtensions(__DRIscreen *psp,
psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0)
psp->image.loader = (__DRIimageLoaderExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_MUTABLE_RENDER_BUFFER_LOADER) == 0)
psp->mutableRenderBuffer.loader = (__DRImutableRenderBufferLoaderExtension *) extensions[i];
}
}

View File

@@ -216,6 +216,10 @@ struct __DRIscreenRec {
const __DRIimageLoaderExtension *loader;
} image;
struct {
const __DRImutableRenderBufferLoaderExtension *loader;
} mutableRenderBuffer;
driOptionCache optionInfo;
driOptionCache optionCache;

View File

@@ -147,7 +147,10 @@ driGetRendererString( char * buffer, const char * hardware_name,
* \param color_depth_match Whether the color depth must match the zs depth
* This forces 32-bit color to have 24-bit depth, and
* 16-bit color to have 16-bit depth.
*
* \param mutable_render_buffer Enable __DRI_ATTRIB_MUTABLE_RENDER_BUFFER,
* which translates to
* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.
*
* \returns
* Pointer to any array of pointers to the \c __DRIconfig structures created
* for the specified formats. If there is an error, \c NULL is returned.
@@ -160,7 +163,8 @@ driCreateConfigs(mesa_format format,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
GLboolean enable_accum, GLboolean color_depth_match)
GLboolean enable_accum, GLboolean color_depth_match,
GLboolean mutable_render_buffer)
{
static const uint32_t masks_table[][4] = {
/* MESA_FORMAT_B5G6R5_UNORM */
@@ -325,6 +329,7 @@ driCreateConfigs(mesa_format format,
modes->yInverted = GL_TRUE;
modes->sRGBCapable = is_srgb;
modes->mutableRenderBuffer = mutable_render_buffer;
}
}
}
@@ -409,6 +414,7 @@ static const struct { unsigned int attrib, offset; } attribMap[] = {
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
__ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
__ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable),
__ATTRIB(__DRI_ATTRIB_MUTABLE_RENDER_BUFFER, mutableRenderBuffer),
/* The struct field doesn't matter here, these are handled by the
* switch in driGetConfigAttribIndex. We need them in the array

View File

@@ -45,7 +45,8 @@ driCreateConfigs(mesa_format format,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
GLboolean enable_accum, GLboolean color_depth_match);
GLboolean enable_accum, GLboolean color_depth_match,
GLboolean mutable_render_buffer);
__DRIconfig **driConcatConfigs(__DRIconfig **a,
__DRIconfig **b);

View File

@@ -1094,7 +1094,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
num_depth_stencil_bits,
back_buffer_modes, 2,
singlesample_samples, 1,
false, false);
false, false, false);
configs = driConcatConfigs(configs, new_configs);
}
@@ -1116,7 +1116,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
depth_bits, stencil_bits, 1,
back_buffer_modes, 1,
singlesample_samples, 1,
true, false);
true, false, false);
configs = driConcatConfigs(configs, new_configs);
}

View File

@@ -239,6 +239,35 @@ intel_flush_front(struct gl_context *ctx)
}
}
static void
brw_display_shared_buffer(struct brw_context *brw)
{
__DRIcontext *dri_context = brw->driContext;
__DRIdrawable *dri_drawable = dri_context->driDrawablePriv;
__DRIscreen *dri_screen = brw->screen->driScrnPriv;
int fence_fd = -1;
if (!brw->is_shared_buffer_bound)
return;
if (!brw->is_shared_buffer_dirty)
return;
if (brw->screen->has_exec_fence) {
/* This function is always called during a flush operation, so there is
* no need to flush again here. But we want to provide a fence_fd to the
* loader, and a redundant flush is the easiest way to acquire one.
*/
if (intel_batchbuffer_flush_fence(brw, -1, &fence_fd))
return;
}
dri_screen->mutableRenderBuffer.loader
->displaySharedBuffer(dri_drawable, fence_fd,
dri_drawable->loaderPrivate);
brw->is_shared_buffer_dirty = false;
}
static void
intel_glFlush(struct gl_context *ctx)
{
@@ -246,7 +275,7 @@ intel_glFlush(struct gl_context *ctx)
intel_batchbuffer_flush(brw);
intel_flush_front(ctx);
brw_display_shared_buffer(brw);
brw->need_flush_throttle = true;
}
@@ -909,7 +938,9 @@ brwCreateContext(gl_api api,
brw->screen = screen;
brw->bufmgr = screen->bufmgr;
brw->has_hiz = devinfo->has_hiz_and_separate_stencil;
/* Braswell has hiz issues, disable it. */
brw->has_hiz = devinfo->has_hiz_and_separate_stencil &&
screen->deviceID != 0x22B1;
brw->has_separate_stencil = devinfo->has_hiz_and_separate_stencil;
brw->has_swizzling = screen->hw_has_swizzling;
@@ -1452,6 +1483,11 @@ intel_prepare_render(struct brw_context *brw)
*/
if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer))
brw->front_buffer_dirty = true;
if (brw->is_shared_buffer_bound) {
/* Subsequent rendering will probably dirty the shared buffer. */
brw->is_shared_buffer_dirty = true;
}
}
/**
@@ -1685,8 +1721,12 @@ intel_update_image_buffer(struct brw_context *intel,
else
last_mt = rb->singlesample_mt;
if (last_mt && last_mt->bo == buffer->bo)
if (last_mt && last_mt->bo == buffer->bo) {
if (buffer_type == __DRI_IMAGE_BUFFER_SHARED) {
intel_miptree_make_shareable(intel, last_mt);
}
return;
}
/* Only allow internal compression if samples == 0. For multisampled
* window system buffers, the only thing the single-sampled buffer is used
@@ -1715,6 +1755,35 @@ intel_update_image_buffer(struct brw_context *intel,
rb->Base.Base.NumSamples > 1) {
intel_renderbuffer_upsample(intel, rb);
}
if (buffer_type == __DRI_IMAGE_BUFFER_SHARED) {
/* The compositor and the application may access this image
* concurrently. The display hardware may even scanout the image while
* the GPU is rendering to it. Aux surfaces cause difficulty with
* concurrent access, so permanently disable aux for this miptree.
*
* Perhaps we could improve overall application performance by
* re-enabling the aux surface when EGL_RENDER_BUFFER transitions to
* EGL_BACK_BUFFER, then disabling it again when EGL_RENDER_BUFFER
* returns to EGL_SINGLE_BUFFER. I expect the wins and losses with this
* approach to be highly dependent on the application's GL usage.
*
* I [chadv] expect clever disabling/reenabling to be counterproductive
* in the use cases I care about: applications that render nearly
* realtime handwriting to the surface while possibly undergiong
* simultaneously scanout as a display plane. The app requires low
* render latency. Even though the app spends most of its time in
* shared-buffer mode, it also frequently transitions between
* shared-buffer (EGL_SINGLE_BUFFER) and double-buffer (EGL_BACK_BUFFER)
* mode. Visual sutter during the transitions should be avoided.
*
* In this case, I [chadv] believe reducing the GPU workload at
* shared-buffer/double-buffer transitions would offer a smoother app
* experience than any savings due to aux compression. But I've
* collected no data to prove my theory.
*/
intel_miptree_make_shareable(intel, mt);
}
}
static void
@@ -1775,4 +1844,19 @@ intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
images.back,
__DRI_IMAGE_BUFFER_BACK);
}
if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) {
assert(images.image_mask == __DRI_IMAGE_BUFFER_SHARED);
drawable->w = images.back->width;
drawable->h = images.back->height;
intel_update_image_buffer(brw,
drawable,
back_rb,
images.back,
__DRI_IMAGE_BUFFER_SHARED);
brw->is_shared_buffer_bound = true;
} else {
brw->is_shared_buffer_bound = false;
brw->is_shared_buffer_dirty = false;
}
}

View File

@@ -790,6 +790,18 @@ struct brw_context
*/
bool front_buffer_dirty;
/**
* True if the __DRIdrawable's current __DRIimageBufferMask is
* __DRI_IMAGE_BUFFER_SHARED.
*/
bool is_shared_buffer_bound;
/**
* True if a shared buffer is bound and it has received any rendering since
* the previous __DRImutableRenderBufferLoaderExtension::displaySharedBuffer().
*/
bool is_shared_buffer_dirty;
/** Framerate throttling: @{ */
struct brw_bo *throttle_batch[2];

View File

@@ -1588,12 +1588,17 @@ static const __DRI2blobExtension intelBlobExtension = {
.set_cache_funcs = brw_set_cache_funcs
};
static const __DRImutableRenderBufferDriverExtension intelMutableRenderBufferExtension = {
.base = { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1 },
};
static const __DRIextension *screenExtensions[] = {
&intelTexBufferExtension.base,
&intelFenceExtension.base,
&intelFlushExtension.base,
&intelImageExtension.base,
&intelRendererQueryExtension.base,
&intelMutableRenderBufferExtension.base,
&dri2ConfigQueryExtension.base,
&dri2NoErrorExtension.base,
&intelBlobExtension.base,
@@ -1606,6 +1611,7 @@ static const __DRIextension *intelRobustScreenExtensions[] = {
&intelFlushExtension.base,
&intelImageExtension.base,
&intelRendererQueryExtension.base,
&intelMutableRenderBufferExtension.base,
&dri2ConfigQueryExtension.base,
&dri2Robustness.base,
&dri2NoErrorExtension.base,
@@ -2159,7 +2165,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
bool allow_rgb10_configs = driQueryOptionb(&screen->optionCache,
"allow_rgb10_configs");
/* Generate singlesample configs without accumulation buffer. */
/* Generate singlesample configs, each without accumulation buffer
* and with EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.
*/
for (unsigned i = 0; i < num_formats; i++) {
__DRIconfig **new_configs;
int num_depth_stencil_bits = 2;
@@ -2195,7 +2203,8 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
num_depth_stencil_bits,
back_buffer_modes, 2,
singlesample_samples, 1,
false, false);
false, false,
/*mutable_render_buffer*/ true);
configs = driConcatConfigs(configs, new_configs);
}
@@ -2222,7 +2231,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
depth_bits, stencil_bits, 1,
back_buffer_modes, 1,
singlesample_samples, 1,
true, false);
true, false, false);
configs = driConcatConfigs(configs, new_configs);
}
@@ -2289,7 +2298,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
back_buffer_modes, 1,
multisample_samples,
num_msaa_modes,
false, false);
false, false, false);
configs = driConcatConfigs(configs, new_configs);
}

View File

@@ -78,7 +78,7 @@ nouveau_get_configs(uint32_t chipset)
ARRAY_SIZE(back_buffer_modes),
msaa_samples,
ARRAY_SIZE(msaa_samples),
GL_TRUE, chipset < 0x10);
GL_TRUE, chipset < 0x10, GL_FALSE);
assert(config);
configs = driConcatConfigs(configs, config);

View File

@@ -804,7 +804,7 @@ __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
ARRAY_SIZE(back_buffer_modes),
msaa_samples_array,
ARRAY_SIZE(msaa_samples_array),
GL_TRUE, GL_FALSE);
GL_TRUE, GL_FALSE, GL_FALSE);
configs = driConcatConfigs(configs, new_configs);
}

View File

@@ -272,7 +272,7 @@ swrastFillInModes(__DRIscreen *psp,
depth_bits_array, stencil_bits_array,
depth_buffer_factor, back_buffer_modes,
back_buffer_factor, msaa_samples_array, 1,
GL_TRUE, GL_FALSE);
GL_TRUE, GL_FALSE, GL_FALSE);
if (configs == NULL) {
fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
__LINE__);

View File

@@ -213,6 +213,9 @@ struct gl_config
/* EXT_framebuffer_sRGB */
GLint sRGBCapable;
/* EGL_KHR_mutable_render_buffer */
GLuint mutableRenderBuffer; /* bool */
};

View File

@@ -656,9 +656,6 @@ st_context_flush(struct st_context_iface *stctxi, unsigned flags,
st->pipe->screen->fence_reference(st->pipe->screen, fence, NULL);
}
if (flags & ST_FLUSH_FRONT)
st_manager_flush_frontbuffer(st);
/* DRI3 changes the framebuffer after SwapBuffers, but we need to invoke
* st_manager_validate_framebuffers to notice that.
*