blob: 4adbd70d5df12bde21cce031fb0fa15e8d8f5c50 [file] [log] [blame]
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("AcronymName")
package androidx.graphics.opengl.egl
import android.opengl.EGL14
/**
* Construct an instance of [EGLConfigAttributes] that includes a mapping of EGL attributes
* to their corresponding value. The full set of attributes can be found here:
* https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglChooseConfig.xhtml
*
* The resultant array of attributes automatically is terminated with EGL_NONE.
*
* For example to create an 8888 configuration, this can be done with the following:
*
* EGLConfigAttributes {
* EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
* EGL14.EGL_RED_SIZE to 8
* EGL14.EGL_GREEN_SIZE to 8
* EGL14.EGL_BLUE_SIZE to 8
* EGL14.EGL_ALPHA_SIZE to 8
* EGL14.EGL_DEPTH_SIZE to 0
* EGL14.EGL_CONFIG_CAVEAT to EGL14.EGL_NONE
* EGL14.EGL_STENCIL_SIZE to 8
* EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
* }
*
* @see EGLConfigAttributes.RGBA_8888
*/
@JvmSynthetic
inline fun EGLConfigAttributes(block: EGLConfigAttributes.Builder.() -> Unit): EGLConfigAttributes =
EGLConfigAttributes.Builder().apply { block() }.build()
@Suppress("AcronymName")
class EGLConfigAttributes internal constructor(
@PublishedApi internal val attrs: IntArray
) {
/**
* Return a copy of the created integer array used for EGL methods.
* Most consumers would pass the [EGLConfigAttributes] instance as a parameter instead, however,
* this method is provided as a convenience for debugging and testing purposes.
*/
fun toArray(): IntArray = attrs.clone()
/**
* Builder used to create an instance of [EGLConfigAttributes]
* Allows for a mapping of EGL configuration attributes to their corresponding
* values as well as including a previously generated [EGLConfigAttributes]
* instance to be used as a template and conditionally update individual mapped values
*/
class Builder @PublishedApi internal constructor() {
private val attrs = HashMap<Int, Int>()
/**
* Map a given EGL configuration attribute key to the given EGL configuration value
*/
@SuppressWarnings("BuilderSetStyle")
@JvmSynthetic
infix fun Int.to(that: Int) {
setAttribute(this, that)
}
/**
* Map a given EGL configuration attribute key to the given EGL configuration value
* @param attribute EGL attribute name such as [EGL14.EGL_RED_SIZE]
* @param value Corresponding value for the [attribute]
*/
@Suppress("MissingGetterMatchingBuilder")
fun setAttribute(attribute: Int, value: Int): Builder {
attrs[attribute] = value
return this
}
/**
* Include all the attributes of the given [EGLConfigAttributes] instance.
* This is useful for creating a new [EGLConfigAttributes] instance with all the same
* attributes as another, allowing for modification of attributes after the fact.
* For example, the following code snippet can be used to create an [EGLConfigAttributes]
* instance that has all the same configuration as [RGBA_8888] but with a
* 16 bit stencil buffer size:
*
* EGLConfigAttributes {
* include(EGLConfigAttributes.RGBA_8888)
* EGL14.EGL_STENCIL_SIZE to 16
* }
*
*
* That is all attributes configured after the include will overwrite the attributes
* configured previously.
*/
@SuppressWarnings("BuilderSetStyle")
fun include(attributes: EGLConfigAttributes) {
val attrsArray = attributes.attrs
for (i in 0 until attrsArray.size - 1 step 2) {
attrs[attrsArray[i]] = attrsArray[i + 1]
}
}
/**
* Construct an instance of [EGLConfigAttributes] with the mappings of integer keys
* to their respective values. This creates a flat integer array with alternating values
* for the key value pairs and ends with EGL_NONE
*/
fun build(): EGLConfigAttributes {
val entries = attrs.entries
val attrArray = IntArray(entries.size * 2 + 1) // Array must end with EGL_NONE
var index = 0
for (entry in entries) {
attrArray[index] = entry.key
attrArray[index + 1] = entry.value
index += 2
}
attrArray[index] = EGL14.EGL_NONE
return EGLConfigAttributes(attrArray)
}
}
companion object {
/**
* EGL configuration attribute used to expose EGLConfigs that support formats with floating
* point RGBA components. This attribute is exposed through the EGL_EXT_pixel_format_float
* EGL extension
*
* See: https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_pixel_format_float.txt
*/
const val EGL_COLOR_COMPONENT_TYPE_EXT = 0x3339
/**
* EGL configuration attribute value that represents fixed point RGBA components
*/
const val EGL_COLOR_COMPONENT_TYPE_FIXED_EXT = 0x333A
/**
* EGL configuration attribute value that represents floating point RGBA components
*/
const val EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT = 0x333B
/**
* EGL Attributes to create an 8 bit EGL config for red, green, blue, and alpha channels as
* well as an 8 bit stencil size
*/
@Suppress("AcronymName")
@JvmField
val RGBA_8888 = EGLConfigAttributes {
EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
EGL14.EGL_RED_SIZE to 8
EGL14.EGL_GREEN_SIZE to 8
EGL14.EGL_BLUE_SIZE to 8
EGL14.EGL_ALPHA_SIZE to 8
EGL14.EGL_DEPTH_SIZE to 0
EGL14.EGL_CONFIG_CAVEAT to EGL14.EGL_NONE
EGL14.EGL_STENCIL_SIZE to 0
EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
}
/**
* EGL Attributes to create a 10 bit EGL config for red, green, blue, channels and a
* 2 bit alpha channels. This does not include any bits for depth and stencil buffers.
*/
@Suppress("AcronymName")
@JvmField
val RGBA_1010102 = EGLConfigAttributes {
EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
EGL14.EGL_RED_SIZE to 10
EGL14.EGL_GREEN_SIZE to 10
EGL14.EGL_BLUE_SIZE to 10
EGL14.EGL_ALPHA_SIZE to 2
EGL14.EGL_DEPTH_SIZE to 0
EGL14.EGL_STENCIL_SIZE to 0
EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
}
/**
* EGL Attributes to create a 16 bit floating point EGL config for red, green, blue and
* alpha channels without a depth or stencil channel.
*/
@Suppress("AcronymName")
@JvmField
val RGBA_F16 = EGLConfigAttributes {
EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
EGL_COLOR_COMPONENT_TYPE_EXT to EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT
EGL14.EGL_RED_SIZE to 16
EGL14.EGL_GREEN_SIZE to 16
EGL14.EGL_BLUE_SIZE to 16
EGL14.EGL_ALPHA_SIZE to 16
EGL14.EGL_DEPTH_SIZE to 0
EGL14.EGL_STENCIL_SIZE to 0
EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
}
}
}