Initial import of userland code

This commit is contained in:
popcornmix
2012-10-24 11:42:57 +01:00
parent c7bc07aea0
commit 729c0e6562
387 changed files with 114245 additions and 3 deletions

104
CMakeLists.txt Normal file
View File

@@ -0,0 +1,104 @@
cmake_minimum_required(VERSION 2.8)
project(vmcs_host_apps)
set(BUILD_MMAL TRUE)
set(BUILD_MMAL_APPS FALSE)
set(vmcs_root ${PROJECT_SOURCE_DIR})
get_filename_component(VIDEOCORE_ROOT . ABSOLUTE)
set(VCOS_PTHREADS_BUILD_SHARED TRUE)
include(makefiles/cmake/global_settings.cmake)
include(makefiles/cmake/arm-linux.cmake)
include(makefiles/cmake/vmcs.cmake)
# Global include paths
include_directories(host_applications/framework)
include_directories(${PROJECT_SOURCE_DIR})
include_directories(interface/vcos/pthreads)
include_directories(interface/vmcs_host/linux)
include_directories(interface/vmcs_host)
include_directories(interface/vmcs_host/khronos)
include_directories(interface/khronos/include)
include_directories(${PROJECT_BINARY_DIR})
include_directories(interface/vchiq_arm)
#include_directories(tools/inet_transport)
include_directories(host_support/include)
# Global compiler flags
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar -Wall -Wno-unused-but-set-variable")
endif()
add_definitions(-D_REENTRANT)
add_definitions(-DUSE_VCHIQ_ARM -DVCHI_BULK_ALIGN=1 -DVCHI_BULK_GRANULARITY=1)
add_definitions(-DOMX_SKIP64BIT)
add_definitions(-DEGL_SERVER_DISPMANX)
add_definitions(-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE)
# do we actually need this?
add_definitions(-D__VIDEOCORE4__)
# add_definitions(-DKHRONOS_CLIENT_LOGGING)
# Check for OpenWF-C value set via command line
if(KHRONOS_EGL_PLATFORM MATCHES "openwfc")
add_definitions(-DKHRONOS_EGL_PLATFORM_OPENWFC)
endif()
# List of subsidiary CMakeLists
add_subdirectory(interface/vcos)
add_subdirectory(interface/vmcs_host)
add_subdirectory(interface/vchiq_arm)
add_subdirectory(interface/khronos)
#add_subdirectory(opensrc/tools/lua)
if(BUILD_MMAL)
include_directories(interface/mmal)
add_subdirectory(interface/mmal)
endif()
#add_subdirectory(containers)
add_subdirectory(middleware/openmaxil)
# 3d demo code
#if(NOT ANDROID)
# add_subdirectory(thirdparty/applications/demos)
# add_subdirectory(opensrc/applications/demos)
#endif()
#if(ENABLE_3D_TESTS)
# add_subdirectory(thirdparty/applications/test)
#endif()
# FIXME: this directory needs a more sensible name and better
# platform factoring
add_subdirectory(interface/usbdk)
# FIXME: we should use a pre-packaged version of freetype
# rather than the one included in the repo.
#add_subdirectory(opensrc/helpers/freetype)
#add_subdirectory(${PROJECT_SOURCE_DIR}/opensrc/helpers/fonts/ttf-bitstream-vera)
# VMCS Host Applications
#add_subdirectory(host_applications/framework)
#add_subdirectory(host_applications/vmcs)
# add_subdirectory(interface/vchiq/test/win32)
# Apps and libraries supporting Camera Tuning Tool
#add_subdirectory(tools/inet_transport/linux)
#add_subdirectory(host_support/vcstandalone)
# add linux apps
add_subdirectory(host_applications/linux)
set(vmcs_host_apps_VERSION_MAJOR 1)
set(vmcs_host_apps_VERSION_MINOR 0)
include_directories("${PROJECT_BINARY_DIR}")
# Remove cache entry, if one added by command line
unset(KHRONOS_EGL_PLATFORM CACHE)

25
LICENCE Normal file
View File

@@ -0,0 +1,25 @@
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,4 +1,6 @@
userland
========
This repository contains the source code for the ARM side libraries used on Raspberry Pi.
These typically are installed in /opt/vc/lib and includes source for the ARM side code to interface to:
EGL, mmal, GLESv2, vcos, openmaxil, vchiq_arm, bcm_host, WFC, OpenVG.
Source code for ARM side libraries for interfacing to Raspberry Pi GPU.
Use buildme to build. It requires cmake to be installed and an arm cross compiler. It is set up to use this one:
https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian

7
buildme Executable file
View File

@@ -0,0 +1,7 @@
#/bin/sh
mkdir -p build/arm-linux/release/
pushd build/arm-linux/release/
cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=Release ../../..
make -j 6
popd

39
helpers/v3d/v3d_common.h Normal file
View File

@@ -0,0 +1,39 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef V3D_COMMON_H
#define V3D_COMMON_H
#include "helpers/v3d/v3d_ver.h"
#include "interface/vcos/vcos_assert.h"
#include "interface/vcos/vcos_stdbool.h"
#include "interface/vcos/vcos_stdint.h"
#include "interface/vcos/vcos_types.h" /* for vcos_unused and VCOS_STATIC_INLINE */
typedef uint32_t V3D_ADDR_T;
typedef uint16_t float16_t;
#endif

63
helpers/v3d/v3d_ver.h Normal file
View File

@@ -0,0 +1,63 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef V3D_VER_H
#define V3D_VER_H
/* if V3D_TECH_VERSION/V3D_REVISION aren't defined, try to figure them out from
* other defines... */
#ifndef V3D_TECH_VERSION
#define V3D_TECH_VERSION 2
#endif
#ifndef V3D_REVISION
#ifdef __BCM2708A0__
#ifdef HERA
/* bcg a1, hera */
#define V3D_REVISION 1
#else
/* 2708 a0 */
#define V3D_REVISION 0
#endif
#elif defined(__BCM2708B0__)
/* 2708 b0 */
#define V3D_REVISION 2
#else
/* fiji */
#define V3D_REVISION 6
#endif
#endif
#define V3D_MAKE_VER(TECH_VERSION, REVISION) (((TECH_VERSION) * 100) + (REVISION))
#define V3D_VER (V3D_MAKE_VER(V3D_TECH_VERSION, V3D_REVISION))
#define V3D_VER_AT_LEAST(TECH_VERSION, REVISION) (V3D_VER >= V3D_MAKE_VER(TECH_VERSION, REVISION))
/* TODO this is temporary */
#if V3D_VER == V3D_MAKE_VER(9, 9)
#define V3D_VER_D3D
#endif
#endif

View File

@@ -0,0 +1,96 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _METADATA_FOURCC_H
#define _METADATA_FOURCC_H
/******************************************************************************
Definition of 4CCs assigned to metadata items. This list acts more as a
central repository of 4CCs for different metadata items so as to avoid clashes.
They are not otherwise necessary for library to function correctly.
******************************************************************************/
/*
Note: Multi-character constants are not valid C and although supported by
some compilers such as Metaware, they are ambiguous in how they should be
packed into a long due to endian-ness (and also due to size for 2 and 3
character constants).
*/
typedef enum {
METADATA_CDI = ('C'<<24)+('D'<<16)+('M'<<8)+('D'), // 'CDMD' struct CDI_METADATA_T in /middleware/camplus/cdi/cdi.h
METADATA_CAM_CAL = ('C'<<24)+('C'<<16)+('A'<<8)+('L'), // 'CCAL' struct CAMERA_CALIBRATION_METADATA_T in /middleware/camplus/cdi/cdi.h
METADATA_TIMING = ('T'<<24)+('I'<<16)+('M'<<8)+('E'), // 'TIME' struct TIMING_METADATA_T in /middleware/camplus/cdi/cdi.h
METADATA_CDI_FILE = ( 0 <<24)+('C'<<16)+('D'<<8)+('F'), // '\x00CDF' struct CDI_FILE_METADATA_T in /middleware/camplus/cdi/cdi_file.h
METADATA_CDI_RAW = ('C'<<24)+('D'<<16)+('R'<<8)+('W'), // 'CDRW' struct CDI_FILE_RAW_METADATA_T in /middleware/camplus/cdi/cdi_file_raw.h
METADATA_STABILISE = ('S'<<24)+('T'<<16)+('A'<<8)+('B'), // 'STAB' struct GLOBAL_MOTION_VECTOR_T in /middleware/camplus/sw/stabilise/stabilise.h
METADATA_LOCAL_MV1 = ('L'<<24)+('M'<<16)+('V'<<8)+('1'), // 'LMV1' struct ALL_LOCAL_MOTION_VECTORS_T in /middleware/camplus/sw/stabilise/stabilise.h
METADATA_LOCAL_MV2 = ('L'<<24)+('M'<<16)+('V'<<8)+('2'), // 'LMV2' struct ALL_LOCAL_MOTION_VECTORS_T in /middleware/camplus/sw/stabilise/stabilise.h
METADATA_TUNER_AGC = ( 0 <<24)+('A'<<16)+('G'<<8)+('C'), // '\x00AGC' struct ISP_AGC_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h
METADATA_AGC_DEBUG = ('A'<<24)+('G'<<16)+('C'<<8)+('D'), // 'AGCD' struct ISP_TUNER_BRCM_AGC_DEBUG_T in /middleware/ISP/tuner/isp_tuner_agc.h
METADATA_FOCUS_REGION = ('F'<<24)+('R'<<16)+('G'<<8)+('N'), // 'FRGN' struct ISP_TUNER_BRCM_AF_STATISTICS_PARAMS_T in /middleware/ISP/tuner/isp_tuner_brcm_common.h
METADATA_FOCUS_WOI = ('F'<<24)+('W'<<16)+('O'<<8)+('I'), // 'FWOI' struct ISP_WOI_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h
METADATA_AUTOFOCUS = ( 0 <<24)+( 0 <<16)+('A'<<8)+('F'), // '\x00\x00AF' struct ISP_AF_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h
METADATA_EV = ('E'<<24)+('V'<<16)+('M'<<8)+('D'), // 'EVMD' struct ISP_TUNER_BRCM_EV_METADATA_T in /middleware/ISP/tuner/isp_tuner_brcm_common.h
METADATA_ISP = ('I'<<24)+('S'<<16)+('P'<<8)+('M'), // 'ISPM' struct ISP_ISP_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h
METADATA_FACETRACKING = ('F'<<24)+('A'<<16)+('C'<<8)+('E'), // 'FACE' struct FACE_METADATA_T defined in /middleware/camplus/sw/face_metadata.h
METADATA_ANTISHAKE = ('S'<<24)+('H'<<16)+('A'<<8)+('K'), // 'SHAK' struct SHAKE_METADATA_T defined in /middleware/camplus/sw/shake_metadata.h
METADATA_RER = ( 0 <<24)+('R'<<16)+('E'<<8)+('R'), // '\x00RER' struct RER_METADATA_T defined in /middleware/camplus/sw/rer_metadata.h
METADATA_SCENEDETECTION = ( 0 <<24)+('A'<<16)+('S'<<8)+('D'), // '\x00ASD' struct ASD_METADATA_T defined in /middleware/camplus/sw/asd_metadata.h
METADATA_TUNER_SYNC = ('S'<<24)+('Y'<<16)+('N'<<8)+('C'), // 'SYNC' NULL data, just adds the item header.
METADATA_DARK_FRAME_CORRECT = ('D'<<24)+('F'<<16)+('R'<<8)+('C'), // 'DFRC' 5 byte literal string "dfrc"
METADATA_DARK_FRAME_SUB = ('D'<<24)+('F'<<16)+('S'<<8)+('B'), // 'DFSB' 3 byte literal string "on"
METADATA_ABL = ( 0 <<24)+('A'<<16)+('B'<<8)+('L'), // '\x00ABL' struct ISP_TUNER_BRCM_BLACK_LEVEL_ABL_T defined in /middleware/ISP/tuner/isp_tuner_brcm_black_level.h
METADATA_DRC = ( 0 <<24)+('D'<<16)+('R'<<8)+('C'), // 'DRC' struct DRC_METADATA_T defined in /middleware/camplus/sw/drc/drc.h
METADATA_REGISTRATION = ( 0 <<24)+('R'<<16)+('E'<<8)+('G'), // 'REG' struct REGISTRATION_OFFSETS_T defined in /middleware/camplus/sw/registration/registration.h
METADATA_RAW_CAPTURE = ('R'<<24)+('W'<<16)+('M'<<8)+('D'), // 'RWMD' struct RAW_CAPTURE_METADATA_T defined in /middleware/camplus/sw/raw_metadata.h
// structure definitions for IL metadata are
// in middleware/openmaxil/headers/ilmetadata.h
METADATA_IL_CAMERA_NAME = ('I'<<24)+('L'<<16)+('C'<<8)+('A'), // 'ILCA'
METADATA_IL_CROP_RECTANGLE = ('I'<<24)+('L'<<16)+('C'<<8)+('R'), // 'ILCR'
METADATA_IL_PIXEL_ASPECT_RATIO = ('I'<<24)+('L'<<16)+('P'<<8)+('A'), // 'ILPA'
METADATA_TUNER_FLASH_MONITOR = ('F'<<24)+('L'<<16)+('M'<<8)+('N'), // 'FLMN' Flash monitor - type ISP_TUNER_BRCM_FLASH_MONITOR_T from isp_tuner_brcm.h
// VoWIFI video analysis
METADATA_SPATIAL_ACT_A = ( 'S'<<24)+('P'<<16)+('T'<<8)+('A'), // 'SPTA' : SPATIAL_ACTIVITY_METADATA_T defined in /middleware/camplus/sw/perceptual/spatial_activity.h
METADATA_TEMPORAL_ACT_A = ( 'T'<<24)+('M'<<16)+('P'<<8)+('A'), // 'TMPA' : TEMPORAL_ACTIVITY_METADATA_T defined in /middleware/camplus/sw/perceptual/temporal_activity.h
METADATA_FILMGRAIN_NOISE_A = ( 'F'<<24)+('G'<<16)+('N'<<8)+('A'), // 'FGNA' : FILMGRAIN_NOISE_METADATA_T defined in /middleware/camplus/sw/perceptual/filmgrain_noise.h
METADATA_COLORSPACE_A = ( 'C'<<24)+('L'<<16)+('R'<<8)+('A'), // 'CLRA' : COLORSPACE_METADATA_T defined in /middleware/camplus/sw/perceptual/colorspace.h
METADATA_FLAT_AREA_A = ( 'F'<<24)+('L'<<16)+('T'<<8)+('A'), // 'FLTA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/flatarea.h
METADATA_STILL_AREA_A = ( 'S'<<24)+('T'<<16)+('L'<<8)+('A'), // 'STLA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/stillarea.h
METADATA_DDITHER_A = ( 'D'<<24)+('D'<<16)+('T'<<8)+('A'), // 'DDTA' : DDITHER_METADATA_T defined in /middleware/camplus/sw/perceptual/...
METADATA_HDR = ( 0 <<24)+( 'H'<<16)+('D'<<8)+('R'), // 'HDR' : HDR_METADATA_T defined in /middleware/camplus/sw/hdr/hdr_metadata.h
METADATA_UNKNOWN = ('U'<<24)+('N'<<16)+('K'<<8)+('N') // 'UNKN'
} METADATA_CODE_T;
#endif

1197
helpers/vc_image/vc_image.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef VC_IMAGE_METADATA_H
#define VC_IMAGE_METADATA_H
#include "vcfw/rtos/rtos.h"
#include "helpers/vc_image/metadata_fourcc.h"
#define VC_METADATA_ALIGN 3
/******************************************************************************
Types of metadata.
******************************************************************************/
typedef unsigned int VC_METADATA_TYPE_T;
/******************************************************************************
Metadata and item headers.
******************************************************************************/
typedef struct vc_metadata_item_s {
VC_METADATA_TYPE_T type;
int len;
} VC_METADATA_ITEM_T;
typedef struct vc_metadata_header_s {
int size;
#ifdef VCMODS_LCC
char readonly;
#else
char readonly:1;
#endif
int offset_next;
RTOS_LATCH_T latch;
} VC_METADATA_HEADER_T;
/******************************************************************************
Public declarations.
******************************************************************************/
// Initialises a metadata header structure
int vc_metadata_initialise(VC_METADATA_HEADER_T *header, int size);
// Add a metadata entry to the buffer
int vc_metadata_add(VC_METADATA_HEADER_T *header, void *data, VC_METADATA_TYPE_T type, int len);
// Get a (pointer to a) particular metadata item from the buffer (optionally copy the data to dest), and return the length of the item
void *vc_metadata_get_with_length(void *dest, VC_METADATA_HEADER_T *header, VC_METADATA_TYPE_T type, int *retcode, int *len);
// Get a (pointer to a) particular metadata item from the buffer (optionally copy the data to dest)
void *vc_metadata_get(void *dest, VC_METADATA_HEADER_T *header, VC_METADATA_TYPE_T type, int *retcode);
// Clear the metadata buffer and reset the header (clears readonly flag)
int vc_metadata_clear(VC_METADATA_HEADER_T *header);
// Set or clear the read-only flag in the metadata buffer
int vc_metadata_set_readonly(VC_METADATA_HEADER_T *header, int value);
// Copies the contents of one metadata buffer to the other (appends the destination buffer)
int vc_metadata_copy(VC_METADATA_HEADER_T *dest, VC_METADATA_HEADER_T *src);
// Overwrites an item in the metadata buffer (caller must make sure the sizes match!)
int vc_metadata_overwrite(VC_METADATA_HEADER_T *header, void *data, VC_METADATA_TYPE_T type);
// Flush the metadata buffer out of the cache
int vc_metadata_cache_flush(VC_METADATA_HEADER_T *header);
// Locks the vc_metadata library semaphore
int vc_metadata_lock(VC_METADATA_HEADER_T *header);
// Unlocks the vc_metadata library semaphore
int vc_metadata_unlock(VC_METADATA_HEADER_T *header);
/******************************************************************************
Wrappers for the above functions using VC_IMAGEs.
******************************************************************************/
#define vc_image_metadata_initialise(i, s) vc_metadata_initialise((i)->metadata, s)
#define vc_image_metadata_add(i, d, t, l) vc_metadata_add((i)->metadata, d, t, l)
#define vc_image_metadata_get(d, i, t, r) vc_metadata_get(d, (i)->metadata, t, r)
#define vc_image_metadata_clear(i) vc_metadata_clear((i)->metadata)
#define vc_image_metadata_set_readonly(i, v) vc_metadata_set_readonly((i)->metadata, v)
#define vc_image_metadata_copy(d, s) vc_metadata_copy((d)->metadata, (s)->metadata)
#define vc_image_metadata_overwrite(i, d, t) vc_metadata_overwrite((i)->metadata, d, t)
#define vc_image_metadata_cache_flush(i) vc_metadata_cache_flush((i)->metadata)
#endif

View File

@@ -0,0 +1,79 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HOST_ILCORE_H
#define HOST_ILCORE_H
#ifdef WANT_OMX_NAME_MANGLE
OMX_API OMX_ERRORTYPE OMX_APIENTRY host_OMX_Init(void);
OMX_API OMX_ERRORTYPE OMX_APIENTRY host_OMX_Deinit(void);
OMX_API OMX_ERRORTYPE OMX_APIENTRY host_OMX_ComponentNameEnum(
OMX_OUT OMX_STRING cComponentName,
OMX_IN OMX_U32 nNameLength,
OMX_IN OMX_U32 nIndex);
OMX_API OMX_ERRORTYPE OMX_APIENTRY host_OMX_GetHandle(
OMX_OUT OMX_HANDLETYPE* pHandle,
OMX_IN OMX_STRING cComponentName,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_CALLBACKTYPE* pCallBacks);
OMX_API OMX_ERRORTYPE OMX_APIENTRY host_OMX_FreeHandle(
OMX_IN OMX_HANDLETYPE hComponent);
OMX_API OMX_ERRORTYPE OMX_APIENTRY host_OMX_SetupTunnel(
OMX_IN OMX_HANDLETYPE hOutput,
OMX_IN OMX_U32 nPortOutput,
OMX_IN OMX_HANDLETYPE hInput,
OMX_IN OMX_U32 nPortInput);
OMX_API OMX_ERRORTYPE host_OMX_GetComponentsOfRole (
OMX_IN OMX_STRING role,
OMX_INOUT OMX_U32 *pNumComps,
OMX_INOUT OMX_U8 **compNames);
OMX_API OMX_ERRORTYPE host_OMX_GetRolesOfComponent (
OMX_IN OMX_STRING compName,
OMX_INOUT OMX_U32 *pNumRoles,
OMX_OUT OMX_U8 **roles);
OMX_ERRORTYPE host_OMX_GetDebugInformation (
OMX_OUT OMX_STRING debugInfo,
OMX_INOUT OMX_S32 *pLen);
#define OMX_Init host_OMX_Init
#define OMX_Deinit host_OMX_Deinit
#define OMX_ComponentNameEnum host_OMX_ComponentNameEnum
#define OMX_GetHandle host_OMX_GetHandle
#define OMX_FreeHandle host_OMX_FreeHandle
#define OMX_SetupTunnel host_OMX_SetupTunnel
#define OMX_GetComponentsOfRole host_OMX_GetComponentsOfRole
#define OMX_GetRolesOfComponent host_OMX_GetRolesOfComponent
#define OMX_GetDebugInformation host_OMX_GetDebugInformation
#else
OMX_ERRORTYPE OMX_GetDebugInformation (
OMX_OUT OMX_STRING debugInfo,
OMX_INOUT OMX_S32 *pLen);
#endif
#endif // HOST_ILCORE_H

View File

@@ -0,0 +1,353 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdarg.h>
//includes
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "interface/vmcs_host/khronos/IL/OMX_Component.h"
#include "interface/vmcs_host/vcilcs.h"
#include "interface/vmcs_host/vchost.h"
#include "interface/vmcs_host/vcilcs_common.h"
#include "host_ilcore.h"
#ifdef WANT_OMX_NAME_MANGLE
#define OMX_Deinit host_OMX_Deinit
#define OMX_Init host_OMX_Init
#define OMX_SetupTunnel host_OMX_SetupTunnel
#define OMX_FreeHandle host_OMX_FreeHandle
#define OMX_GetHandle host_OMX_GetHandle
#define OMX_GetRolesOfComponent host_OMX_GetRolesOfComponent
#define OMX_GetComponentsOfRole host_OMX_GetComponentsOfRole
#define OMX_ComponentNameEnum host_OMX_ComponentNameEnum
#define OMX_GetDebugInformation host_OMX_GetDebugInformation
#endif
#ifdef WANT_LOCAL_OMX
// xxx: we need to link to local OpenMAX IL core as well
OMX_API OMX_ERRORTYPE OMX_APIENTRY vc_OMX_Init(void);
OMX_API OMX_ERRORTYPE OMX_APIENTRY vc_OMX_Deinit(void);
OMX_API OMX_ERRORTYPE OMX_APIENTRY vc_OMX_GetHandle(
OMX_OUT OMX_HANDLETYPE* pHandle,
OMX_IN OMX_STRING cComponentName,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_CALLBACKTYPE* pCallBacks);
OMX_API OMX_ERRORTYPE OMX_APIENTRY vc_OMX_FreeHandle(
OMX_IN OMX_HANDLETYPE hComponent);
#endif
static int coreInit = 0;
static int nActiveHandles = 0;
static ILCS_SERVICE_T *ilcs_service = NULL;
static VCOS_MUTEX_T lock;
static VCOS_ONCE_T once = VCOS_ONCE_INIT;
/* Atomic creation of lock protecting shared state */
static void initOnce(void)
{
VCOS_STATUS_T status;
status = vcos_mutex_create(&lock, VCOS_FUNCTION);
vcos_demand(status == VCOS_SUCCESS);
}
/* OMX_Init */
OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void)
{
VCOS_STATUS_T status;
OMX_ERRORTYPE err = OMX_ErrorNone;
status = vcos_once(&once, initOnce);
vcos_demand(status == VCOS_SUCCESS);
vcos_mutex_lock(&lock);
#ifdef WANT_LOCAL_OMX
vc_OMX_Init(); // initialise local core first
#endif
if(coreInit == 0)
{
// we need to connect via an ILCS connection to VideoCore
VCHI_INSTANCE_T initialise_instance;
VCHI_CONNECTION_T *connection;
ILCS_CONFIG_T config;
vc_host_get_vchi_state(&initialise_instance, &connection);
vcilcs_config(&config);
#ifdef USE_VCHIQ_ARM
ilcs_service = ilcs_init((VCHIQ_INSTANCE_T) initialise_instance, (void **) &connection, &config, 0);
#else
ilcs_service = ilcs_init((VCHIQ_STATE_T *) initialise_instance, (void **) &connection, &config, 0);
#endif
if(ilcs_service == NULL)
{
err = OMX_ErrorHardware;
goto end;
}
coreInit = 1;
}
#ifdef USE_VCHIQ_ARM
else
coreInit++;
#endif
end:
vcos_mutex_unlock(&lock);
return err;
}
/* OMX_Deinit */
OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void)
{
if(coreInit == 0) // || (coreInit == 1 && nActiveHandles > 0))
return OMX_ErrorNotReady;
vcos_mutex_lock(&lock);
#ifdef USE_VCHIQ_ARM
coreInit--;
#endif
if(coreInit == 0)
{
// we need to teardown the ILCS connection to VideoCore
ilcs_deinit(ilcs_service);
ilcs_service = NULL;
}
#ifdef WANT_LOCAL_OMX
vc_OMX_Deinit(); // deinitialise local core as well
#endif
vcos_mutex_unlock(&lock);
return OMX_ErrorNone;
}
/* OMX_ComponentNameEnum */
OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
OMX_OUT OMX_STRING cComponentName,
OMX_IN OMX_U32 nNameLength,
OMX_IN OMX_U32 nIndex)
{
if(ilcs_service == NULL)
return OMX_ErrorBadParameter;
return vcil_out_component_name_enum(ilcs_get_common(ilcs_service), cComponentName, nNameLength, nIndex);
}
/* OMX_GetHandle */
OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
OMX_OUT OMX_HANDLETYPE* pHandle,
OMX_IN OMX_STRING cComponentName,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_CALLBACKTYPE* pCallBacks)
{
OMX_ERRORTYPE eError;
OMX_COMPONENTTYPE *pComp;
OMX_HANDLETYPE hHandle = 0;
if (pHandle == NULL || cComponentName == NULL || pCallBacks == NULL || ilcs_service == NULL)
{
if(pHandle)
*pHandle = NULL;
return OMX_ErrorBadParameter;
}
#if defined(WANT_LOCAL_OMX) && 0
if ((eError = vc_OMX_GetHandle(pHandle, cComponentName, pAppData, pCallBacks)) != OMX_ErrorNone)
#endif
{
pComp = (OMX_COMPONENTTYPE *)malloc(sizeof(OMX_COMPONENTTYPE));
if (!pComp)
{
vcos_assert(0);
return OMX_ErrorInsufficientResources;
}
memset(pComp, 0, sizeof(OMX_COMPONENTTYPE));
hHandle = (OMX_HANDLETYPE)pComp;
pComp->nSize = sizeof(OMX_COMPONENTTYPE);
pComp->nVersion.nVersion = OMX_VERSION;
eError = vcil_out_create_component(ilcs_get_common(ilcs_service), hHandle, cComponentName);
if (eError == OMX_ErrorNone) {
// Check that all function pointers have been filled in.
// All fields should be non-zero.
int i;
uint32_t *p = (uint32_t *) pComp;
for(i=0; i<sizeof(OMX_COMPONENTTYPE)>>2; i++)
if(*p++ == 0)
eError = OMX_ErrorInvalidComponent;
if(eError != OMX_ErrorNone && pComp->ComponentDeInit)
pComp->ComponentDeInit(hHandle);
}
if (eError == OMX_ErrorNone) {
eError = pComp->SetCallbacks(hHandle,pCallBacks,pAppData);
if (eError != OMX_ErrorNone)
pComp->ComponentDeInit(hHandle);
}
if (eError == OMX_ErrorNone) {
*pHandle = hHandle;
}
else {
*pHandle = NULL;
free(pComp);
}
}
if (eError == OMX_ErrorNone) {
vcos_mutex_lock(&lock);
nActiveHandles++;
vcos_mutex_unlock(&lock);
}
return eError;
}
/* OMX_FreeHandle */
OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
OMX_IN OMX_HANDLETYPE hComponent)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_COMPONENTTYPE *pComp;
if (hComponent == NULL || ilcs_service == NULL)
return OMX_ErrorBadParameter;
pComp = (OMX_COMPONENTTYPE*)hComponent;
#ifdef WANT_LOCAL_OMX
// xxx: a bit of a bodge, we rely on knowing that
// the local core doesn't make use of this field but
// ILCS does...
if (pComp->pApplicationPrivate == NULL)
return vc_OMX_FreeHandle(hComponent);
#endif
if (ilcs_service == NULL)
return OMX_ErrorBadParameter;
eError = (pComp->ComponentDeInit)(hComponent);
if (eError == OMX_ErrorNone) {
vcos_mutex_lock(&lock);
--nActiveHandles;
vcos_mutex_unlock(&lock);
free(pComp);
}
vcos_assert(nActiveHandles >= 0);
return eError;
}
/* OMX_SetupTunnel */
OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
OMX_IN OMX_HANDLETYPE hOutput,
OMX_IN OMX_U32 nPortOutput,
OMX_IN OMX_HANDLETYPE hInput,
OMX_IN OMX_U32 nPortInput)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_COMPONENTTYPE *pCompIn, *pCompOut;
OMX_TUNNELSETUPTYPE oTunnelSetup;
if ((hOutput == NULL && hInput == NULL) || ilcs_service == NULL)
return OMX_ErrorBadParameter;
oTunnelSetup.nTunnelFlags = 0;
oTunnelSetup.eSupplier = OMX_BufferSupplyUnspecified;
pCompOut = (OMX_COMPONENTTYPE*)hOutput;
if (hOutput){
eError = pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, hInput, nPortInput, &oTunnelSetup);
}
if (eError == OMX_ErrorNone && hInput) {
pCompIn = (OMX_COMPONENTTYPE*)hInput;
eError = pCompIn->ComponentTunnelRequest(hInput, nPortInput, hOutput, nPortOutput, &oTunnelSetup);
if (eError != OMX_ErrorNone && hOutput) {
/* cancel tunnel request on output port since input port failed */
pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, NULL, 0, NULL);
}
}
return eError;
}
/* OMX_GetComponentsOfRole */
OMX_ERRORTYPE OMX_GetComponentsOfRole (
OMX_IN OMX_STRING role,
OMX_INOUT OMX_U32 *pNumComps,
OMX_INOUT OMX_U8 **compNames)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
*pNumComps = 0;
return eError;
}
/* OMX_GetRolesOfComponent */
OMX_ERRORTYPE OMX_GetRolesOfComponent (
OMX_IN OMX_STRING compName,
OMX_INOUT OMX_U32 *pNumRoles,
OMX_OUT OMX_U8 **roles)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
*pNumRoles = 0;
return eError;
}
/* OMX_GetDebugInformation */
OMX_ERRORTYPE OMX_GetDebugInformation (
OMX_OUT OMX_STRING debugInfo,
OMX_INOUT OMX_S32 *pLen)
{
if(ilcs_service == NULL)
return OMX_ErrorBadParameter;
return vcil_out_get_debug_information(ilcs_get_common(ilcs_service), debugInfo, pLen);
}
/* File EOF */

View File

@@ -0,0 +1,39 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HOST_APP_H
#define HOST_APP_H
#include "platform.h"
//Definition for the single message handler, as provided by the host app.
extern void host_app_message_handler( const uint16_t msg, const uint32_t param1, const uint32_t param2);
//Definition for a function that returns the host app's name
extern char *host_app_name( void );
#endif /* HOST_APP_H */

View File

@@ -0,0 +1,360 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PLATFORM_H
#define PLATFORM_H
#include "interface/vmcs_host/vchost.h"
#include "interface/vcos/vcos.h"
/******************************************************************************
Global typedefs, macros and constants
******************************************************************************/
/* the definition of all the message types that a
platform can send to the message handler */
typedef enum
{
/* A message sent at the start of the day
Param 1 = 0
Param 2 = 0 */
PLATFORM_MSG_INIT,
/*A message sent at the end of the day
Param 1 = 0
Param 2 = 0 */
PLATFORM_MSG_END,
/*A message sent when a button action occurs
Param 1 = the button ID
Param 2 = the hold time - only valid for repeat button presses */
PLATFORM_MSG_BUTTON_PRESS,
PLATFORM_MSG_BUTTON_REPEAT,
PLATFORM_MSG_BUTTON_RELEASE,
/*A message sent when a timer event occurs
Param 1 = the timer ID
Param 2 = 0 */
PLATFORM_MSG_TIMER_TICK,
/*A message sent when a hostreq notify is sent from VMCS
Param 1 = the event id
Param 2 = event param */
PLATFORM_MSG_HOSTREQ_NOTIFY,
/*A touchscreen event
Param 1 = the event id
Param 2 = event param */
PLATFORM_MSG_TOUCHSCREEN_EVENT,
/* user messages go here */
PLATFORM_MSG_USER
} PLATFORM_MSG_T;
/* the definitions of the buttons in the system
Current these are mapped to the VC02DK */
typedef enum
{
//The push buttons
PLATFORM_BUTTON_A = 0x0001,
PLATFORM_BUTTON_B = 0x0002,
PLATFORM_BUTTON_C = 0x0004,
PLATFORM_BUTTON_D = 0x0008,
PLATFORM_BUTTON_E = 0x0010,
//The joystick moves
PLATFORM_BUTTON_DOWN = 0x0020,
PLATFORM_BUTTON_LEFT = 0x0040,
PLATFORM_BUTTON_UP = 0x0080,
PLATFORM_BUTTON_RIGHT = 0x0100,
PLATFORM_BUTTON_Z = 0x0200,
PLATFORM_BUTTON_PAGE_UP = 0x0400,
PLATFORM_BUTTON_PAGE_DOWN = 0x0800,
//Some extra buttons for HDMI/TV
PLATFORM_BUTTON_HDMI0 = 0x1000,
PLATFORM_BUTTON_HDMI1 = 0x2000,
PLATFORM_BUTTON_HDMI2 = 0x4000,
PLATFORM_BUTTON_TV = 0x8000,
//Some extra buttons for CEC
PLATFORM_BUTTON_CEC0 = 0x10000,
PLATFORM_BUTTON_CEC1 = 0x20000
//UPDATE THE NUMBER OF BUTTONS BELOW IF YOU EDIT THESE
} PLATFORM_BUTTON_T;
//the max number of buttons definition
#define PLATFORM_NUMBER_BUTTONS 18
/* the touchscreen events */
typedef enum
{
PLATFORM_TOUCHSCREEN_EVENT_MIN,
PLATFORM_TOUCHSCREEN_EVENT_GESTURE_RIGHT,
PLATFORM_TOUCHSCREEN_EVENT_GESTURE_LEFT,
PLATFORM_TOUCHSCREEN_EVENT_GESTURE_DOWN,
PLATFORM_TOUCHSCREEN_EVENT_GESTURE_UP,
PLATFORM_TOUCHSCREEN_EVENT_PRESS,
PLATFORM_TOUCHSCREEN_EVENT_PRESS_DOUBLE_TAP,
PLATFORM_TOUCHSCREEN_EVENT_PRESS_AND_HOLD,
PLATFORM_TOUCHSCREEN_EVENT_PINCH_IN,
PLATFORM_TOUCHSCREEN_EVENT_SPREAD_OUT,
PLATFORM_TOUCHSCREEN_EVENT_FINGER_DOWN,
PLATFORM_TOUCHSCREEN_EVENT_FINGER_UP,
PLATFORM_TOUCHSCREEN_EVENT_MAX
} PLATFORM_TOUCHSCREEN_EVENT_T;
//define the max file path
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
//The default buffer size of the general command response
#define PLATFORM_DEFAULT_RESPONSE_BUF_SIZE (uint32_t)(128)
#define PLATFORM_DEFAULT_REQUEST_BUF_SIZE (uint32_t)(128)
//the max number of timers which an app can use
#define PLATFORM_MAX_NUM_TIMERS 6
//the starting id for the timers
#define PLATFORM_TIMER_START_ID 0
/* Definition for a platfor message handler - returning FALSE means that the app wishes to quit */
typedef int32_t (*PLATFORM_MESSAGE_HANDLER_T)( const uint16_t msg,
const uint32_t param1,
const uint32_t param2 );
/******************************************************************************
Global Message funcs definitions
******************************************************************************/
// routines used to post a message to the platform message handle
VCHPRE_ int32_t VCHPOST_ platform_post_message( const uint16_t msg,
const uint32_t param1,
const uint32_t param2);
/******************************************************************************
Global Task funcs definitions
******************************************************************************/
// Definition for a platform thread function
typedef int32_t (*PLATFORM_THREAD_FUNC_T)( void *param );
// Definition for a platform thread handle
typedef void *PLATFORM_THREAD_T;
// routine used to create a new thread. This thread will be passed the void *param when created
// NOTE: the 'thread_func' MUST call the platform_thread_exit function before leaving the context of the function
VCHPRE_ PLATFORM_THREAD_T VCHPOST_ platform_thread_create( PLATFORM_THREAD_FUNC_T thread_func,
void *param );
//Routine to set a threads priority
VCHPRE_ int32_t VCHPOST_ platform_thread_set_priority(PLATFORM_THREAD_T thread,
const uint32_t priority );
//Routine to exit a thead (called from within the thread)
//NOTE! You must call this function before exiting a thread.
VCHPRE_ void VCHPOST_ platform_thread_exit( void );
//Routine used to wait until a thread has exited
VCHPRE_ int32_t VCHPOST_ platform_thread_join( PLATFORM_THREAD_T thread );
/******************************************************************************
Semaphore funcs definitions
******************************************************************************/
//definition of a semaphore
struct PLATFORM_SEMAPHORE;
typedef struct PLATFORM_SEMAPHORE *PLATFORM_SEMAPHORE_T;
//Routine to create a semaphore. Seeds the semaphore with an initial count
VCHPRE_ int32_t VCHPOST_ platform_semaphore_create( PLATFORM_SEMAPHORE_T *semaphore, const uint32_t inital_count );
//Routine to delete a semaphore
VCHPRE_ int32_t VCHPOST_ platform_semaphore_delete( PLATFORM_SEMAPHORE_T *semaphore );
//Routine used to wait for a semaphore to be free (will suspend the calling thread if not available)
VCHPRE_ int32_t VCHPOST_ platform_semaphore_wait( PLATFORM_SEMAPHORE_T *semaphore );
//Routine used to post (increment) a semaphore. used to release any tasks waiting on the semaphore
VCHPRE_ int32_t VCHPOST_ platform_semaphore_post( PLATFORM_SEMAPHORE_T *semaphore );
/******************************************************************************
Global Event funcs definitions
******************************************************************************/
// Definition of an event group
struct PLATFORM_EVENTGROUP;
typedef struct PLATFORM_EVENTGROUP *PLATFORM_EVENTGROUP_T;
//Event group flags
typedef enum
{
PLATFORM_EVENTGROUP_OPERATION_MIN,
PLATFORM_EVENTGROUP_OPERATION_AND,
PLATFORM_EVENTGROUP_OPERATION_OR,
PLATFORM_EVENTGROUP_OPERATION_AND_CONSUME,
PLATFORM_EVENTGROUP_OPERATION_OR_CONSUME,
PLATFORM_EVENTGROUP_OPERATION_MAX
} PLATFORM_EVENTGROUP_OPERATION_T;
#define PLATFORM_EVENTGROUP_SUSPEND -1
#define PLATFORM_EVENTGROUP_NO_SUSPEND 0
//Routines used to create an event group
VCHPRE_ int32_t VCHPOST_ platform_eventgroup_create( PLATFORM_EVENTGROUP_T *eventgroup );
//Routines used to delete an event group
VCHPRE_ int32_t VCHPOST_ platform_eventgroup_delete( PLATFORM_EVENTGROUP_T *eventgroup );
//Routines used to set a bit in an eventgroup
VCHPRE_ int32_t VCHPOST_ platform_eventgroup_set( PLATFORM_EVENTGROUP_T *eventgroup,
const uint32_t bitmask,
const PLATFORM_EVENTGROUP_OPERATION_T operation );
//Routine used to wait for bits in an eventgroup to be set
VCHPRE_ int32_t VCHPOST_ platform_eventgroup_get( PLATFORM_EVENTGROUP_T *eventgroup,
const uint32_t bitmask,
const PLATFORM_EVENTGROUP_OPERATION_T operation,
const uint32_t suspend,
uint32_t *retrieved_bits );
/******************************************************************************
Global Timer func definitions
******************************************************************************/
// Routines used to start / stop a single timer for the host app platform
VCHPRE_ int32_t VCHPOST_ platform_timer_start( const uint32_t timer_id,
const uint32_t timer_period );
VCHPRE_ int32_t VCHPOST_ platform_timer_stop( const uint32_t timer_id );
// Routine to change the timer resolution
VCHPRE_ int32_t VCHPOST_ platform_timer_reschedule(const uint32_t timer_id,
const uint32_t timer_period );
/******************************************************************************
Global C library style func definitions
******************************************************************************/
// routine to set the button repeat rate
VCHPRE_ void VCHPOST_ platform_set_button_repeat_time( const uint32_t repeat_rate_in_ms );
// routine to enable / disable a host req message
VCHPRE_ int32_t VCHPOST_ platform_enable_hostreq_notify( const uint32_t notify_event, const uint32_t enable );
// routine to sleep the platform
VCHPRE_ void VCHPOST_ platform_sleep( const uint32_t sleep_time_in_ms );
// routine to get the local resource path
VCHPRE_ char * VCHPOST_ platform_get_local_resource_path( void );
// routine perform a str comparison with case sensitivity
VCHPRE_ int32_t VCHPOST_ platform_stricmp( const char *str1, const char *str2 );
// routine to return the number of ticks since the start of day, in ms
VCHPRE_ int32_t VCHPOST_ platform_get_ticks( void );
// routine to send out debug print messages to the platform host
VCHPRE_ void VCHPOST_ platform_debug_print( const char *string, ... );
//Routine to malloc a section of memory - has addition line and file parameters for debug
VCHPRE_ void * VCHPOST_ platform_malloc( const uint32_t size_in_bytes,
const int line,
const char *file );
//Routine to malloc and clear a section of memory - has addition line and file parameters for debug
VCHPRE_ void * VCHPOST_ platform_calloc( const uint32_t num,
const uint32_t size_in_bytes,
const int line,
const char *file );
// Routine to free memory previously malloc'd
VCHPRE_ void VCHPOST_ platform_free( void *buffer );
//Routine to allocate memory on specific alignment
VCHPRE_ void *VCHPOST_ platform_malloc_aligned( const uint32_t size_in_bytes,
unsigned int align,
const char *description);
//Routine to query if we are connected to VMCS or not
VCHPRE_ uint32_t VCHPOST_ platform_get_vmcs_connected_status( void );
//Routine to create + return the hosts native debug window handle
VCHPRE_ uint32_t VCHPOST_ platform_create_and_get_debug_window_handle( void );
//Routine to get the platforms screen size
VCHPRE_ int32_t VCHPOST_ platform_get_screen_size( uint32_t *width,
uint32_t *height );
//Set the height of the buttons created along the bottom of the touchscreen. The
//format is Q8 fixed-point fraction of the screen - e.g. 0x80 will give you buttons
//half the height of the screen. If zero, no buttons are created.
VCHPRE_ int32_t VCHPOST_ platform_set_touchscreen_buttons_height(uint32_t xHeight);
//Translate gestures (left/right/up/down) into the joystick equivalents.
VCHPRE_ int32_t VCHPOST_ platform_translate_gestures_to_joystick(int);
//Set the size of the screen in an alternative coordinate system.
// scaled_width - scaled X width of the touch screen area
// scaled_height - scaled Y height of the touch screen area
VCHPRE_ int32_t VCHPOST_ platform_set_touchscreen_scale(int scaled_width, int scaled_height);
//Return the scaled location of the fingers currently in contact with the
//touchscreen.
VCHPRE_ int32_t /*rc*/ VCHPOST_ platform_touch_finger_scaled_pos(
int *out_x, int *out_y,
int *out_pressure, int *out_width);
#endif /* PLATFORM_H */
/**************************** End of file ************************************/

View File

@@ -0,0 +1,12 @@
# linux apps
add_subdirectory(libs/bcm_host)
add_subdirectory(apps/gencmd)
add_subdirectory(apps/tvservice)
if(ALL_APPS)
add_subdirectory(apps/vcdbg)
add_subdirectory(apps/edid_parser)
add_subdirectory(apps/hello_pi)
endif()

View File

@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 2.8)
if (WIN32)
set(VCOS_PLATFORM win32)
else ()
set(VCOS_PLATFORM pthreads)
add_definitions(-Wall -Werror)
endif ()
include_directories( ../../../..
../../../../interface/vcos
../../../../interface/vcos/${VCOS_PLATFORM} )
#add_subdirectory( ../../../../interface/vcos/${VCOS_PLATFORM} vcos)
#add_subdirectory( ../../bin/gencmd)
add_executable(vcgencmd gencmd.c)
target_link_libraries(vcgencmd vcos vchiq_arm vchostif)
install(TARGETS vcgencmd RUNTIME DESTINATION bin)

View File

@@ -0,0 +1,146 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* ---- Include Files ---------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include "interface/vmcs_host/vc_vchi_gencmd.h"
int main( int argc, char **argv )
{
int instNum = 0;
VCHI_INSTANCE_T vchi_instance;
VCHI_CONNECTION_T *vchi_connection;
if ( argc > 1 )
{
if (( strcmp( argv[1], "0" ) == 0 ) || ( strcmp( argv[1], "1" ) == 0 ))
{
instNum = atoi( argv[1] );
argv++;
argc--;
}
}
vcos_init();
if ( vchi_initialise( &vchi_instance ) != 0)
{
printf( "VCHI initialization failed\n" );
return -1;
}
//create a vchi connection
if ( vchi_connect( NULL, 0, vchi_instance ) != 0)
{
printf( "VCHI connection failed\n" );
return -1;
}
vc_vchi_gencmd_init(vchi_instance, &vchi_connection, 1 );
if (argc > 1)
{
int i = 1;
char buffer[ 1024 ];
clock_t before=0, after=0;
double time_diff;
uint32_t show_time = 0;
int ret;
//reset the string
strcpy( buffer, "" );
//first, strip out a potential leading -t
if( strcmp( argv[1], "-t" ) == 0 )
{
show_time = 1;
i++;
}
for (; i <= argc-1; i++)
{
strcat( buffer, argv[i] );
strcat( buffer, " " );
}
if( show_time )
before = clock();
//send the gencmd for the argument
if (( ret = vc_gencmd_send( buffer )) != 0 )
{
printf( "vc_gencmd_send returned %d\n", ret );
}
//get + print out the response!
if (( ret = vc_gencmd_read_response( buffer, sizeof( buffer ) )) != 0 )
{
printf( "vc_gencmd_read_response returned %d\n", ret );
}
if( show_time )
after = clock();
if( show_time )
{
time_diff = ((double) (after - before)) / CLOCKS_PER_SEC;
printf( "Time took %f seconds (%f msecs) (%f usecs)\n", time_diff, time_diff * 1000, time_diff * 1000000 );
}
if ( buffer[0] != '\0' )
{
if ( buffer[ strlen( buffer) - 1] == '\n' )
{
fputs( buffer, stdout );
}
else
{
printf("%s\n", buffer );
}
}
}
vc_gencmd_stop();
//close the vchi connection
if ( vchi_disconnect( vchi_instance ) != 0)
{
printf( "VCHI disconnect failed\n" );
return -1;
}
return 0;
}

View File

@@ -0,0 +1,5 @@
add_executable(tvservice tvservice.c)
target_link_libraries(tvservice vchostif)
install(TARGETS tvservice
RUNTIME DESTINATION bin)

View File

@@ -0,0 +1,806 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// ---- Include Files -------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <signal.h>
#include <assert.h>
#include <string.h>
#include "interface/vmcs_host/vc_tvservice.h"
// ---- Public Variables ----------------------------------------------------
// ---- Private Constants and Types -----------------------------------------
// Logging macros (for remapping to other logging mechanisms, i.e., vcos_log)
#define LOG_ERR( fmt, arg... ) fprintf( stderr, "[E] " fmt "\n", ##arg )
#define LOG_WARN( fmt, arg... ) fprintf( stderr, "[W] " fmt "\n", ##arg )
#define LOG_INFO( fmt, arg... ) fprintf( stderr, "[I] " fmt "\n", ##arg )
#define LOG_DBG( fmt, arg... ) fprintf( stdout, "[D] " fmt "\n", ##arg )
// Standard output log (for printing normal information to users)
#define LOG_STD( fmt, arg... ) fprintf( stdout, fmt "\n", ##arg )
// Maximum length of option string (3 characters max for each option + NULL)
#define OPTSTRING_LEN ( sizeof( long_opts ) / sizeof( *long_opts ) * 3 + 1 )
// ---- Private Variables ---------------------------------------------------
enum
{
OPT_PREFERRED = 'p',
OPT_EXPLICIT = 'e',
OPT_OFF = 'o',
OPT_SDTVON = 'n',
OPT_MODES = 'm',
OPT_MONITOR = 'M',
OPT_STATUS = 's',
OPT_DUMPEDID = 'd',
OPT_AUDIOSUP = 'a',
OPT_SHOWINFO = 'i',
OPT_HELP = 'h',
// Options from this point onwards don't have any short option equivalents
OPT_FIRST_LONG_OPT = 0x80,
};
static struct option long_opts[] =
{
// name has_arg flag val
// ------------------- ------------------ ---- ---------------
{ "preferred", no_argument, NULL, OPT_PREFERRED },
{ "explicit", required_argument, NULL, OPT_EXPLICIT },
{ "off", no_argument, NULL, OPT_OFF },
{ "sdtvon", required_argument, NULL, OPT_SDTVON },
{ "modes", required_argument, NULL, OPT_MODES },
{ "monitor", no_argument, NULL, OPT_MONITOR },
{ "status", no_argument, NULL, OPT_STATUS },
{ "dumpedid", required_argument, NULL, OPT_DUMPEDID},
{ "audio", no_argument, NULL, OPT_AUDIOSUP},
{ "info", required_argument, NULL, OPT_SHOWINFO},
{ "help", no_argument, NULL, OPT_HELP },
{ 0, 0, 0, 0 }
};
static VCOS_EVENT_T quit_event;
// ---- Private Functions ---------------------------------------------------
static void show_usage( void )
{
LOG_STD( "Usage: tvservice [OPTION]..." );
LOG_STD( " -p, --preferred Power on HDMI with preferred settings" );
LOG_STD( " -e, --explicit=\"GROUP MODE\" Power on HDMI with explicit GROUP (CEA, DMT, CEA_3D)\n"
" and MODE (see --modes)" );
LOG_STD( " -n, --sdtvon=\"MODE ASPECT\" Power on SDTV with MODE (PAL or NTSC) and ASPECT (4:3 14:9 or 16:9)" );
LOG_STD( " -o, --off Power off the display" );
LOG_STD( " -m, --modes=GROUP Get supported modes for GROUP (CEA, DMT, CEA_3D)" );
LOG_STD( " -M, --monitor Monitor HDMI events" );
LOG_STD( " -s, --status Get HDMI status" );
LOG_STD( " -a, --audio Get supported audio information" );
LOG_STD( " -d, --dumpedid <filename> Dump EDID information to file" );
LOG_STD( " -h, --help Print this information" );
}
static void create_optstring( char *optstring )
{
char *short_opts = optstring;
struct option *option;
// Figure out the short options from our options structure
for ( option = long_opts; option->name != NULL; option++ )
{
if (( option->flag == NULL ) && ( option->val < OPT_FIRST_LONG_OPT ))
{
*short_opts++ = (char)option->val;
if ( option->has_arg != no_argument )
{
*short_opts++ = ':';
}
// Optional arguments require two ':'
if ( option->has_arg == optional_argument )
{
*short_opts++ = ':';
}
}
}
*short_opts++ = '\0';
}
static int get_modes( HDMI_RES_GROUP_T group )
{
TV_SUPPORTED_MODE_T supported_modes[TV_MAX_SUPPORTED_MODES];
HDMI_RES_GROUP_T preferred_group;
uint32_t preferred_mode;
int num_modes;
int i;
vcos_assert(( group == HDMI_RES_GROUP_CEA ) ||
( group == HDMI_RES_GROUP_DMT ) ||
( group == HDMI_RES_GROUP_CEA_3D ));
num_modes = vc_tv_hdmi_get_supported_modes( group, supported_modes,
TV_MAX_SUPPORTED_MODES,
&preferred_group,
&preferred_mode );
if ( num_modes < 0 )
{
LOG_ERR( "Failed to get modes" );
return -1;
}
LOG_STD( "Group %s has %u modes:",
group == HDMI_RES_GROUP_CEA ? "CEA" : group == HDMI_RES_GROUP_DMT ? "DMT" : "CEA_3D", num_modes );
for ( i = 0; i < num_modes; i++ )
{
LOG_STD( "%s mode %u: %ux%u @ %uHz, %s",
supported_modes[i].native ? " (native)" : " ",
supported_modes[i].code, supported_modes[i].width,
supported_modes[i].height, supported_modes[i].frame_rate,
supported_modes[i].scan_mode ? "interlaced" : "progressive" );
}
return 0;
}
static int get_status( void )
{
TV_GET_STATE_RESP_T tvstate = {0};
static const char *status_str[] = {
"HPD low",
"HPD high",
"DVI mode",
"HDMI mode",
"HDCP off",
"HDCP on",
"", "", "", "", "", "", "", "", "", "", //end of HDMI states
"", "", //Currently we don't have a way to detect these
"NTSC mode", "PAL mode",
"composite CP off", "composite CP on",
"", "", "", "", "", "", "", "", "", ""
};
static char status[256] = {0};
char *s = &status[0];
int i;
vc_tv_get_state( &tvstate );
for(i = 0; i < 16; i++) {
if(tvstate.state & (1 << i)) {
s += sprintf(s, "%s|", status_str[i]);
}
}
if((tvstate.state & (VC_HDMI_DVI|VC_HDMI_HDMI)) == 0)
s += sprintf(s, "HDMI off|");
if(tvstate.state & (VC_SDTV_NTSC|VC_SDTV_PAL)) {
for(i = 18; i < 31; i++) {
if(tvstate.state & (1 << i)) {
s += sprintf(s, "%s|", status_str[i]);
}
}
} else {
s += sprintf(s, "composite off|");
}
*(--s) = '\0';
if(tvstate.width && tvstate.height) {
LOG_STD( "state: %s (0x%x), %ux%u @ %uHz, %s", status, tvstate.state,
tvstate.width, tvstate.height, tvstate.frame_rate,
tvstate.scan_mode ? "interlaced" : "progressive" );
} else {
LOG_STD( "state: %s (0x%x), HDMI powered off", status, tvstate.state);
}
return 0;
}
static int get_audiosup( void )
{
uint8_t sample_rates[] = {32, 44, 48, 88, 96, 176, 192};
uint8_t sample_sizes[] = {16, 20, 24};
const char *formats[] = {"Reserved", "PCM", "AC3", "MPEG1", "MP3", "MPEG2", "AAC", "DTS", "ATRAC", "DSD", "EAC3", "DTS_HD", "MLP", "DST", "WMAPRO", "Extended"};
int i, j, k;
for (k=EDID_AudioFormat_ePCM; k<EDID_AudioFormat_eMaxCount; k++) {
int num_channels = 0, max_sample_rate = 0, max_sample_size = 0;
for (i=1; i<=8; i++) {
if (vc_tv_hdmi_audio_supported(k, i, EDID_AudioSampleRate_e44KHz, EDID_AudioSampleSize_16bit ) == 0)
num_channels = i;
}
for (i=0, j=EDID_AudioSampleRate_e32KHz; j<=EDID_AudioSampleRate_e192KHz; i++, j<<=1) {
if (vc_tv_hdmi_audio_supported(k, 1, j, EDID_AudioSampleSize_16bit ) == 0)
max_sample_rate = i;
}
if (k==EDID_AudioFormat_ePCM) {
for (i=0, j=EDID_AudioSampleSize_16bit; j<=EDID_AudioSampleSize_24bit; i++, j<<=1) {
if (vc_tv_hdmi_audio_supported(k, 1, EDID_AudioSampleRate_e44KHz, j ) == 0)
max_sample_size = i;
}
if (num_channels>0)
LOG_STD("%8s supported: Max channels: %d, Max samplerate:%4dkHz, Max samplesize %2d bits.", formats[k], num_channels, sample_rates[max_sample_rate], sample_sizes[max_sample_size]);
} else {
for (i=0; i<256; i++) {
if (vc_tv_hdmi_audio_supported(k, 1, EDID_AudioSampleRate_e44KHz, i ) == 0)
max_sample_size = i;
}
if (num_channels>0)
LOG_STD("%8s supported: Max channels: %d, Max samplerate:%4dkHz, Max rate %4d kb/s.", formats[k], num_channels, sample_rates[max_sample_rate], 8*max_sample_size);
}
}
return 0;
}
static int dump_edid( const char *filename )
{
uint8_t buffer[128];
int written = 0, offset = 0, i, extensions = 0;
FILE *fp = fopen(filename, "wb");
int siz = vc_tv_hdmi_ddc_read(offset, sizeof (buffer), buffer);
offset += sizeof( buffer);
/* First block always exist */
if (fp && siz == sizeof(buffer)) {
written += fwrite(buffer, 1, sizeof buffer, fp);
extensions = buffer[0x7e]; /* This tells you how many more blocks to read */
for(i = 0; i < extensions; i++, offset += sizeof( buffer)) {
siz = vc_tv_hdmi_ddc_read(offset, sizeof( buffer), buffer);
if(siz == sizeof(buffer)) {
written += fwrite(buffer, 1, sizeof (buffer), fp);
} else {
break;
}
}
}
if (fp)
fclose(fp);
LOG_STD( "Written %d bytes to %s", written, filename);
return written < sizeof(buffer);
}
static int show_info( int on )
{
return vc_tv_show_info(on);
}
static void control_c( int signum )
{
(void)signum;
LOG_STD( "Shutting down..." );
vcos_event_signal( &quit_event );
}
static void tvservice_callback( void *callback_data,
uint32_t reason,
uint32_t param1,
uint32_t param2 )
{
(void)callback_data;
(void)param1;
(void)param2;
switch ( reason )
{
case VC_HDMI_UNPLUGGED:
{
LOG_INFO( "HDMI cable is unplugged" );
break;
}
case VC_HDMI_STANDBY:
{
LOG_INFO( "HDMI in standby mode" );
break;
}
case VC_HDMI_DVI:
{
LOG_INFO( "HDMI in DVI mode" );
break;
}
case VC_HDMI_HDMI:
{
LOG_INFO( "HDMI in HDMI mode" );
break;
}
case VC_HDMI_HDCP_UNAUTH:
{
LOG_INFO( "HDCP authentication is broken" );
break;
}
case VC_HDMI_HDCP_AUTH:
{
LOG_INFO( "HDCP is active" );
break;
}
case VC_HDMI_HDCP_KEY_DOWNLOAD:
{
LOG_INFO( "HDCP key download" );
break;
}
case VC_HDMI_HDCP_SRM_DOWNLOAD:
{
LOG_INFO( "HDCP revocation list download" );
break;
}
default:
{
// Ignore all other reasons
break;
}
}
}
static int start_monitor( void )
{
if ( vcos_event_create( &quit_event, "tvservice" ) != VCOS_SUCCESS )
{
LOG_ERR( "Failed to create quit event" );
return -1;
}
// Handle the INT and TERM signals so we can quit
signal( SIGINT, control_c );
signal( SIGTERM, control_c );
vc_tv_register_callback( &tvservice_callback, NULL );
return 0;
}
static int power_on_preferred( void )
{
int ret;
LOG_STD( "Powering on HDMI with preferred settings" );
ret = vc_tv_hdmi_power_on_preferred();
if ( ret != 0 )
{
LOG_ERR( "Failed to power on HDMI with preferred settings" );
}
return ret;
}
static int power_on_explicit( HDMI_RES_GROUP_T group,
uint32_t mode )
{
int ret;
LOG_STD( "Powering on HDMI with explicit settings (%s mode %u)",
group == HDMI_RES_GROUP_CEA ? "CEA" : group == HDMI_RES_GROUP_DMT ? "DMT" : "CEA_3D", mode );
ret = vc_tv_hdmi_power_on_explicit( HDMI_MODE_HDMI, group, mode );
if ( ret != 0 )
{
LOG_ERR( "Failed to power on HDMI with explicit settings (%s mode %u)",
group == HDMI_RES_GROUP_CEA ? "CEA" : group == HDMI_RES_GROUP_DMT ? "DMT" : "CEA_3D", mode );
}
return ret;
}
static int power_on_sdtv( SDTV_MODE_T mode,
SDTV_ASPECT_T aspect )
{
int ret;
SDTV_OPTIONS_T options;
memset(&options, 0, sizeof options);
options.aspect = aspect;
LOG_STD( "Powering on SDTV with explicit settings (mode:%d aspect:%d)",
mode, aspect );
ret = vc_tv_sdtv_power_on(mode, &options);
if ( ret != 0 )
{
LOG_ERR( "Failed to power on SDTV with explicit settings (mode:%d aspect:%d)",
mode, aspect );
}
return ret;
}
static int power_off( void )
{
int ret;
LOG_STD( "Powering off HDMI");
ret = vc_tv_power_off();
if ( ret != 0 )
{
LOG_ERR( "Failed to power off HDMI" );
}
return ret;
}
// ---- Public Functions -----------------------------------------------------
int main( int argc, char **argv )
{
int32_t ret;
char optstring[OPTSTRING_LEN];
int opt;
int opt_preferred = 0;
int opt_explicit = 0;
int opt_sdtvon = 0;
int opt_off = 0;
int opt_modes = 0;
int opt_monitor = 0;
int opt_status = 0;
int opt_audiosup = 0;
int opt_dumpedid = 0;
int opt_showinfo = 0;
char *dumpedid_filename = NULL;
VCHI_INSTANCE_T vchi_instance;
VCHI_CONNECTION_T *vchi_connection;
HDMI_RES_GROUP_T power_on_explicit_group = HDMI_RES_GROUP_INVALID;
uint32_t power_on_explicit_mode;
HDMI_RES_GROUP_T get_modes_group = HDMI_RES_GROUP_INVALID;
SDTV_MODE_T sdtvon_mode;
SDTV_ASPECT_T sdtvon_aspect;
// Initialize VCOS
vcos_init();
// Create the option string that we will be using to parse the arguments
create_optstring( optstring );
// Parse the command line arguments
while (( opt = getopt_long_only( argc, argv, optstring, long_opts,
NULL )) != -1 )
{
switch ( opt )
{
case 0:
{
// getopt_long returns 0 for entries where flag is non-NULL
break;
}
case OPT_PREFERRED:
{
opt_preferred = 1;
break;
}
case OPT_EXPLICIT:
{
char group_str[32];
if ( sscanf( optarg, "%s %u", group_str,
&power_on_explicit_mode ) != 2 )
{
LOG_ERR( "Invalid arguments '%s'", optarg );
goto err_out;
}
// Check the group first
if ( vcos_strcasecmp( "CEA", group_str ) == 0 )
{
power_on_explicit_group = HDMI_RES_GROUP_CEA;
}
else if ( vcos_strcasecmp( "DMT", group_str ) == 0 )
{
power_on_explicit_group = HDMI_RES_GROUP_DMT;
}
else if ( vcos_strcasecmp( "CEA_3D", group_str ) == 0 )
{
power_on_explicit_group = HDMI_RES_GROUP_CEA_3D;
}
else
{
LOG_ERR( "Invalid group '%s'", group_str );
goto err_out;
}
// Then check if mode is a sane number
if ( power_on_explicit_mode > 256 )
{
LOG_ERR( "Invalid mode '%u'", power_on_explicit_mode );
goto err_out;
}
opt_explicit = 1;
break;
}
case OPT_SDTVON:
{
char mode_str[32], aspect_str[32];
if ( sscanf( optarg, "%s %s", mode_str,
aspect_str ) != 2 )
{
LOG_ERR( "Invalid arguments '%s'", optarg );
goto err_out;
}
// Check the group first
if ( vcos_strcasecmp( "NTSC", mode_str ) == 0 )
{
sdtvon_mode = SDTV_MODE_NTSC;
}
else if ( vcos_strcasecmp( "NTSC_J", mode_str ) == 0 )
{
sdtvon_mode = SDTV_MODE_NTSC_J;
}
else if ( vcos_strcasecmp( "PAL", mode_str ) == 0 )
{
sdtvon_mode = SDTV_MODE_PAL;
}
else if ( vcos_strcasecmp( "PAL_M", mode_str ) == 0 )
{
sdtvon_mode = SDTV_MODE_PAL_M;
}
else
{
LOG_ERR( "Invalid mode '%s'", mode_str );
goto err_out;
}
if ( vcos_strcasecmp( "4:3", aspect_str ) == 0 )
{
sdtvon_aspect = SDTV_ASPECT_4_3;
}
else if ( vcos_strcasecmp( "14:9", aspect_str ) == 0 )
{
sdtvon_aspect = SDTV_ASPECT_14_9;
}
else if ( vcos_strcasecmp( "16:9", aspect_str ) == 0 )
{
sdtvon_aspect = SDTV_ASPECT_16_9;
}
opt_sdtvon = 1;
break;
}
case OPT_OFF:
{
opt_off = 1;
break;
}
case OPT_MODES:
{
if ( vcos_strcasecmp( "CEA", optarg ) == 0 )
{
get_modes_group = HDMI_RES_GROUP_CEA;
}
else if ( vcos_strcasecmp( "DMT", optarg ) == 0 )
{
get_modes_group = HDMI_RES_GROUP_DMT;
}
else if ( vcos_strcasecmp( "CEA_3D", optarg ) == 0 )
{
get_modes_group = HDMI_RES_GROUP_CEA_3D;
}
else
{
LOG_ERR( "Invalid group '%s'", optarg );
goto err_out;
}
opt_modes = 1;
break;
}
case OPT_MONITOR:
{
opt_monitor = 1;
break;
}
case OPT_STATUS:
{
opt_status = 1;
break;
}
case OPT_AUDIOSUP:
{
opt_audiosup = 1;
break;
}
case OPT_DUMPEDID:
{
opt_dumpedid = 1;
dumpedid_filename = optarg;
break;
}
case OPT_SHOWINFO:
{
opt_showinfo = atoi(optarg)+1;
break;
}
default:
{
LOG_ERR( "Unrecognized option '%d'\n", opt );
}
case '?':
case OPT_HELP:
{
goto err_usage;
}
} // end switch
} // end while
argc -= optind;
argv += optind;
if (( optind == 1 ) || ( argc > 0 ))
{
if ( argc > 0 )
{
LOG_ERR( "Unrecognized argument -- '%s'", *argv );
}
goto err_usage;
}
if (( opt_preferred + opt_explicit + opt_sdtvon > 1 ))
{
LOG_ERR( "Conflicting power on options" );
goto err_usage;
}
if ((( opt_preferred == 1 ) || ( opt_explicit == 1 ) || ( opt_sdtvon == 1)) && ( opt_off == 1 ))
{
LOG_ERR( "Cannot power on and power off simultaneously" );
goto err_out;
}
// Initialize the VCHI connection
ret = vchi_initialise( &vchi_instance );
if ( ret != 0 )
{
LOG_ERR( "Failed to initialize VCHI (ret=%d)", ret );
goto err_out;
}
ret = vchi_connect( NULL, 0, vchi_instance );
if ( ret != 0)
{
LOG_ERR( "Failed to create VCHI connection (ret=%d)", ret );
goto err_out;
}
// LOG_INFO( "Starting tvservice" );
// Initialize the tvservice
vc_vchi_tv_init( vchi_instance, &vchi_connection, 1 );
if ( opt_monitor == 1 )
{
LOG_STD( "Starting to monitor for HDMI events" );
if ( start_monitor() != 0 )
{
goto err_stop_service;
}
}
if ( opt_modes == 1 )
{
if ( get_modes( get_modes_group ) != 0 )
{
goto err_stop_service;
}
}
if ( opt_preferred == 1 )
{
if ( power_on_preferred() != 0 )
{
goto err_stop_service;
}
}
else if ( opt_explicit == 1 )
{
if ( power_on_explicit( power_on_explicit_group,
power_on_explicit_mode ) != 0 )
{
goto err_stop_service;
}
}
else if ( opt_sdtvon == 1 )
{
if ( power_on_sdtv( sdtvon_mode,
sdtvon_aspect ) != 0 )
{
goto err_stop_service;
}
}
else if (opt_off == 1 )
{
if ( power_off() != 0 )
{
goto err_stop_service;
}
}
if ( opt_status == 1 )
{
if ( get_status() != 0 )
{
goto err_stop_service;
}
}
if ( opt_audiosup == 1 )
{
if ( get_audiosup() != 0 )
{
goto err_stop_service;
}
}
if ( opt_dumpedid == 1 )
{
if ( dump_edid(dumpedid_filename) != 0 )
{
goto err_stop_service;
}
}
if ( opt_showinfo )
{
if ( show_info(opt_showinfo-1) != 0 )
{
goto err_stop_service;
}
}
if ( opt_monitor == 1 )
{
// Wait until we get the signal to exit
vcos_event_wait( &quit_event );
vcos_event_delete( &quit_event );
}
err_stop_service:
// LOG_INFO( "Stopping tvservice" );
// Stop the tvservice
vc_vchi_tv_stop();
// Disconnect the VCHI connection
vchi_disconnect( vchi_instance );
exit( 0 );
err_usage:
show_usage();
err_out:
exit( 1 );
}

View File

@@ -0,0 +1,22 @@
if (WIN32)
set(VCOS_PLATFORM win32)
else ()
set(VCOS_PLATFORM pthreads)
add_definitions(-Wall -Werror)
endif ()
include_directories( ../../../..
../../../../interface/vcos/${VCOS_PLATFORM}
../../../../host_support/linux/added/include
../../../../host_applications/vmcs/test_apps/iltest
../../../../host_applications/framework/common )
add_library(bcm_host ${SHARED} bcm_host.c
../../../../interface/vmcs_host/linux/vcfilesys.c
../../../../interface/vmcs_host/linux/vcfiled/vcfiled_check.c)
target_link_libraries(bcm_host vcos vchostif)
install(TARGETS bcm_host DESTINATION lib)

View File

@@ -0,0 +1,146 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "interface/vmcs_host/vc_dispmanx.h"
#include "interface/vmcs_host/vc_vchi_gencmd.h"
#include "interface/vmcs_host/vc_vchi_bufman.h"
#include "interface/vmcs_host/vc_tvservice.h"
#include "interface/vmcs_host/vc_cecservice.h"
#include "interface/vchiq_arm/vchiq_if.h"
static VCHI_INSTANCE_T global_initialise_instance;
static VCHI_CONNECTION_T *global_connection;
int32_t graphics_get_display_size( const uint16_t display_number,
uint32_t *width,
uint32_t *height)
{
DISPMANX_DISPLAY_HANDLE_T display_handle = 0;
DISPMANX_MODEINFO_T mode_info;
int32_t success = -1;
if (display_handle == 0) {
// Display must be opened first.
display_handle = vc_dispmanx_display_open(display_number);
vcos_assert(display_handle);
}
if (display_handle) {
success = vc_dispmanx_display_get_info(display_handle, &mode_info);
if( success >= 0 )
{
if( NULL != width )
{
*width = mode_info.width;
}
if( NULL != height )
{
*height = mode_info.height;
}
}
}
if ( display_handle )
{
vc_dispmanx_display_close(display_handle);
display_handle = 0;
}
return success;
}
void host_app_message_handler(void)
{
printf("host_app_message_handler\n");
}
void vc_host_get_vchi_state(VCHI_INSTANCE_T *initialise_instance, VCHI_CONNECTION_T **connection)
{
if (initialise_instance) *initialise_instance = global_initialise_instance;
if (connection) *connection = global_connection;
}
void bcm_host_init(void)
{
VCHIQ_INSTANCE_T vchiq_instance;
static int initted;
int success = -1;
char response[ 128 ];
if (initted)
return;
initted = 1;
vcos_init();
if (vchiq_initialise(&vchiq_instance) != VCHIQ_SUCCESS)
{
printf("* failed to open vchiq instance\n");
exit(-1);
}
vcos_log("vchi_initialise");
success = vchi_initialise( &global_initialise_instance);
vcos_assert(success == 0);
vchiq_instance = (VCHIQ_INSTANCE_T)global_initialise_instance;
global_connection = vchi_create_connection(single_get_func_table(),
vchi_mphi_message_driver_func_table());
vcos_log("vchi_connect");
vchi_connect(&global_connection, 1, global_initialise_instance);
vc_vchi_gencmd_init (global_initialise_instance, &global_connection, 1);
vc_vchi_dispmanx_init (global_initialise_instance, &global_connection, 1);
vc_vchi_tv_init (global_initialise_instance, &global_connection, 1);
vc_vchi_cec_init (global_initialise_instance, &global_connection, 1);
//vc_vchi_bufman_init (global_initialise_instance, &global_connection, 1);
if ( success == 0 )
{
success = vc_gencmd( response, sizeof(response), "set_vll_dir /sd/vlls" );
vcos_assert( success == 0 );
}
}
void bcm_host_deinit(void)
{
}
// Fix linking problems. These are referenced by libs, but shouldn't be called
int eglIntOpenMAXILDoneMarker (void* component_handle, void * egl_image)
{
vcos_assert(0);
return 0;
}
void wfc_stream_await_buffer(void * stream)
{
vcos_assert(0);
}

View File

@@ -0,0 +1,29 @@
#ifndef VMCS_CONFIG_H
#define VMCS_CONFIG_H
/*
* Autogenerated by cmake from host_applications/vmcs/vmcs_config.h.in
*/
/** Root location to look for installed resources.
*/
#define VMCS_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
/** Where to start looking for media files.
*/
#define VMCS_MEDIA_ROOT "/sd"
/** We can't use pakfs - it relies on vc_filesys since only
* VC understands PAK files, but vc_filesys can only be used
* by VC itself or in response to a VC request inside the file
* server.
*/
#define NO_PAKFS 1
/** Don't try to check the disks after iltests. That's just silly
* on linux.
*/
#define ILTEST_NO_DISK_CHECKS
#endif

View File

@@ -0,0 +1,178 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined( VC_DEBUG_SYM_H )
#define VC_DEBUG_SYM_H
/* ---- Include Files ----------------------------------------------------- */
#include <stddef.h>
#include "interface/vcos/vcos_stdint.h"
/* ---- Constants and Types ---------------------------------------------- */
typedef struct
{
const char *label;
uint32_t addr;
size_t size;
} VC_DEBUG_SYMBOL_T;
typedef struct
{
uint32_t symbolTableOffset;
uint32_t magic;
uint32_t paramSize;
} VC_DEBUG_HEADER_T;
typedef struct
{
uint32_t vcMemBase;
uint32_t vcMemSize;
uint32_t vcEntryPoint;
uint32_t symbolTableLength;
} VC_DEBUG_PARAMS_T;
#define VC_DEBUG_HEADER_MAGIC (('V' << 0) + ('C' << 8) + ('D' << 16) + ('H' << 24))
// Offset within the videocore memory map to get the address of the debug header.
#define VC_DEBUG_HEADER_OFFSET 0x2800
#if defined( __VC4_BIG_ISLAND__ ) || defined (PLATFORM_RASPBERRYPI)
/* Use of the debug symbols only makes sense on machines which have
* some type of shared memory architecture.
*/
# define USE_VC_DEBUG_SYMS 1
#else
# define USE_VC_DEBUG_SYMS 0
#endif
#if USE_VC_DEBUG_SYMS
# define PRAGMA(foo) pragma foo
#else
# define PRAGMA(foo)
#endif
/*
* NOTE: The section name has to start with .init or the linker will
* purge it out of the image (since nobody has any references to these).
*/
#if USE_VC_DEBUG_SYMS
#define VC_DEBUG_SYMBOL(name,label,addr,size) \
PRAGMA( Data(LIT, ".init.vc_debug_sym" ); ) \
static const VC_DEBUG_SYMBOL_T vc_sym_##name = { label, (uint32_t)addr, size }; \
PRAGMA( Data )
#else
#define VC_DEBUG_SYMBOL(name,label,addr,size)
#endif
#define VC_DEBUG_VAR(var) VC_DEBUG_SYMBOL(var,#var,&var,sizeof(var))
/*
* When using VC_DEBUG_VAR, you typically want to use uncached memory, otherwise
* it will go in cached memory and the host won't get a coherent view of the
* memory. So we take advantage of the .ucdata section which gets linked into
* the uncached memory space.
*
* Now this causes another problem, namely that the videocore linker ld/st
* instructions only have 27-bit relocations, and accessing a global from
* uncached memory is more than 27-bits away. So we create a couple of macros
* which can be used to declare a variable and put it into the .ucdata section
* and another macro which will dereference it as if it were a pointer.
*
* To use:
*
* VC_DEBUG_DECLARE_UNCACHED_VAR( int, foo, 0xCafeBeef );
* #define foo VC_DEBUG_ACCESS_UNCACHED_VAR(foo)
*/
#define VC_DEBUG_DECLARE_UNCACHED_VAR(var_type,var_name,var_init) \
PRAGMA( Data(".ucdata"); ) \
var_type var_name = (var_init); \
PRAGMA( Data(); ) \
var_type *vc_var_ptr_##var_name = &var_name; \
VC_DEBUG_VAR(var_name)
#define VC_DEBUG_DECLARE_UNCACHED_STATIC_VAR(var_type,var_name,var_init) \
PRAGMA( Data(".ucdata"); ) \
static var_type var_name = (var_init); \
PRAGMA( Data(); ) \
static var_type *vc_var_ptr_##var_name = &var_name; \
VC_DEBUG_VAR(var_name)
#define VC_DEBUG_DECLARE_UNCACHED_VAR_ZERO(var_type,var_name) \
PRAGMA( Data(".ucdata"); ) \
var_type var_name = {0}; \
PRAGMA( Data(); ) \
var_type *vc_var_ptr_##var_name = &var_name; \
VC_DEBUG_VAR(var_name)
#define VC_DEBUG_DECLARE_UNCACHED_STATIC_VAR_ZERO(var_type,var_name) \
PRAGMA( Data(".ucdata"); ) \
static var_type var_name = {0}; \
PRAGMA( Data(); ) \
static var_type *vc_var_ptr_##var_name = &var_name; \
VC_DEBUG_VAR(var_name)
#define VC_DEBUG_ACCESS_UNCACHED_VAR(var_name) (*vc_var_ptr_##var_name)
/*
* Declare a constant character string. This doesn't need to be uncached
* since it never changes.
*/
#define VC_DEBUG_DECLARE_STRING_VAR(var_name,var_init) \
const char var_name[] = var_init; \
VC_DEBUG_VAR(var_name)
/*
* Since some variable aren't actually referenced by the videocore
* this variant uses a .init.* section to ensure that the variable
* doesn't get pruned by the linker.
*/
#define VC_DEBUG_DECLARE_UNCACHED_STATIC_VAR_NO_PTR(var_type,var_name,var_init) \
PRAGMA( Data(".init.ucdata"); ) \
static var_type var_name = (var_init); \
PRAGMA( Data(); ) \
VC_DEBUG_VAR(var_name)
/* ---- Variable Externs ------------------------------------------------- */
#if USE_VC_DEBUG_SYMS
extern VC_DEBUG_SYMBOL_T __VC_DEBUG_SYM_START[];
extern VC_DEBUG_SYMBOL_T __VC_DEBUG_SYM_END[];
#endif
/* ---- Function Prototypes ---------------------------------------------- */
#endif /* VC_DEBUG_SYM_H */

View File

@@ -0,0 +1,75 @@
# Khronos
#
# Note: in Android the linker is unable or unwilling to resolve
# dynamically using already loaded symbols. The libraries here
# have quite a few circular dependencies, and so the only way
# to make it work seems to be to have everything static.
set(EGL_SOURCE
egl/egl_client_config.c
egl/egl_client_context.c
egl/egl_client.c
egl/egl_client_get_proc.c
egl/egl_client_surface.c
ext/egl_brcm_driver_monitor_client.c
ext/egl_brcm_perf_monitor_client.c
ext/egl_brcm_global_image_client.c
ext/egl_brcm_flush_client.c
ext/egl_khr_image_client.c
ext/egl_khr_sync_client.c
ext/gl_oes_egl_image_client.c
ext/egl_khr_lock_surface_client.c
ext/ext_gl_debug_marker.c
common/khrn_int_image.c
common/khrn_int_util.c
common/khrn_options.c
common/khrn_client_global_image_map.c
common/linux/khrn_client_rpc_linux.c
common/linux/khrn_client_platform_linux.c
vg/vg_int_mat3x3.c
vg/vg_client.c
common/khrn_client.c
ext/egl_openmaxil_client.c
# ../vmcs_host/vc_vchi_dispmanx.c
ext/gl_oes_draw_texture_client.c
ext/gl_oes_query_matrix_client.c
ext/gl_oes_framebuffer_object.c
ext/gl_oes_map_buffer.c
ext/gl_oes_matrix_palette_client.c)
set(GLES_SOURCE
glxx/glxx_client.c)
set(VG_SOURCE
vg/vg_client.c
vg/vg_int_mat3x3.c)
set(WFC_SOURCE
wf/wfc_client_stream.c
wf/wfc_client.c
wf/wfc_client_server_api.c
wf/wfc_client_ipc.c
common/openwfc/khrn_client_platform_openwfc.c)
set(CLIENT_SOURCE
common/khrn_client_pointermap.c
common/khrn_client_vector.c
common/khrn_int_hash.c
common/khrn_client_cache.c)
add_library(EGL ${SHARED} ${EGL_SOURCE})
add_library(GLESv2 ${SHARED} ${GLES_SOURCE})
add_library(OpenVG ${SHARED} ${VG_SOURCE})
add_library(WFC ${SHARED} ${WFC_SOURCE})
add_library(khrn_client ${CLIENT_SOURCE})
# TODO do we need EGL_static and GLESv2_static now that khrn_static exists?
add_library(EGL_static STATIC ${EGL_SOURCE})
add_library(GLESv2_static STATIC ${GLES_SOURCE})
add_library(khrn_static STATIC
${EGL_SOURCE} ${GLES_SOURCE} ${VG_SOURCE} ${WFC_SOURCE} ${CLIENT_SOURCE})
target_link_libraries(EGL khrn_client vchiq_arm vcos bcm_host -lm)
target_link_libraries(GLESv2 EGL khrn_client vcos)
target_link_libraries(WFC EGL)
target_link_libraries(OpenVG EGL)
install(TARGETS EGL GLESv2 OpenVG WFC khrn_client DESTINATION lib)
install(TARGETS EGL_static GLESv2_static khrn_static DESTINATION lib)

View File

@@ -0,0 +1,113 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_PLATFORM_ABSTRACT_H
#define KHRN_CLIENT_PLATFORM_ABSTRACT_H
#include "interface/vcos/vcos.h"
typedef int KHR_STATUS_T;
#define KHR_SUCCESS 0
/*
mutex
*/
typedef struct PLATFORM_MUTEX_T
{
/* nothing needed here */
#if defined(_MSC_VER) || defined(__CC_ARM)
char dummy; /* empty structures are not allowed */
#endif
} PLATFORM_MUTEX_T;
VCOS_STATIC_INLINE
VCOS_STATUS_T platform_mutex_create(PLATFORM_MUTEX_T *mutex) {
UNUSED(mutex);
// Nothing to do
return VCOS_SUCCESS;
}
VCOS_STATIC_INLINE
void platform_mutex_destroy(PLATFORM_MUTEX_T *mutex)
{
UNUSED(mutex);
/* Nothing to do */
}
VCOS_STATIC_INLINE
void platform_mutex_acquire(PLATFORM_MUTEX_T *mutex)
{
UNUSED(mutex);
/* Nothing to do */
}
VCOS_STATIC_INLINE
void platform_mutex_release(PLATFORM_MUTEX_T *mutex)
{
UNUSED(mutex);
/* Nothing to do */
}
/*
named counting semaphore
*/
typedef VCOS_NAMED_SEMAPHORE_T PLATFORM_SEMAPHORE_T;
/*
VCOS_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int name[3], int count);
Preconditions:
sem is a valid pointer to an uninitialised variable
name is a valid pointer to three elements
Postconditions:
If return value is KHR_SUCCESS then sem contains a valid PLATFORM_SEMAPHORE_T
*/
extern VCOS_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int name[3], int count);
extern void khronos_platform_semaphore_destroy(PLATFORM_SEMAPHORE_T *sem);
extern void khronos_platform_semaphore_acquire(PLATFORM_SEMAPHORE_T *sem);
extern void khronos_platform_semaphore_release(PLATFORM_SEMAPHORE_T *sem);
/*
thread-local storage
*/
typedef void *PLATFORM_TLS_T;
extern VCOS_STATUS_T platform_tls_create(PLATFORM_TLS_T *tls);
extern void platform_tls_destroy(PLATFORM_TLS_T tls);
extern void platform_tls_set(PLATFORM_TLS_T tls, void *v);
extern void *platform_tls_get(PLATFORM_TLS_T tls);
extern void* platform_tls_get_check(PLATFORM_TLS_T tls);
extern void platform_tls_remove(PLATFORM_TLS_T tls);
#endif

View File

@@ -0,0 +1,113 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_PLATFORM_FILLER_DIRECT_H
#define KHRN_CLIENT_PLATFORM_FILLER_DIRECT_H
#include "interface/vcos/vcos.h"
typedef int KHR_STATUS_T;
#define KHR_SUCCESS 0
/*
mutex
*/
typedef struct PLATFORM_MUTEX_T
{
/* nothing needed here */
#if defined(_MSC_VER) || defined(__CC_ARM)
char dummy; /* empty structures are not allowed */
#endif
} PLATFORM_MUTEX_T;
VCOS_STATIC_INLINE
VCOS_STATUS_T platform_mutex_create(PLATFORM_MUTEX_T *mutex) {
UNUSED(mutex);
// Nothing to do
return VCOS_SUCCESS;
}
VCOS_STATIC_INLINE
void platform_mutex_destroy(PLATFORM_MUTEX_T *mutex)
{
UNUSED(mutex);
/* Nothing to do */
}
VCOS_STATIC_INLINE
void platform_mutex_acquire(PLATFORM_MUTEX_T *mutex)
{
UNUSED(mutex);
/* Nothing to do */
}
VCOS_STATIC_INLINE
void platform_mutex_release(PLATFORM_MUTEX_T *mutex)
{
UNUSED(mutex);
/* Nothing to do */
}
/*
named counting semaphore
*/
typedef VCOS_NAMED_SEMAPHORE_T PLATFORM_SEMAPHORE_T;
/*
VCOS_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int name[3], int count);
Preconditions:
sem is a valid pointer to an uninitialised variable
name is a valid pointer to three elements
Postconditions:
If return value is KHR_SUCCESS then sem contains a valid PLATFORM_SEMAPHORE_T
*/
extern VCOS_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int name[3], int count);
extern void khronos_platform_semaphore_destroy(PLATFORM_SEMAPHORE_T *sem);
extern void khronos_platform_semaphore_acquire(PLATFORM_SEMAPHORE_T *sem);
extern void khronos_platform_semaphore_release(PLATFORM_SEMAPHORE_T *sem);
/*
thread-local storage
*/
typedef void *PLATFORM_TLS_T;
extern VCOS_STATUS_T platform_tls_create(PLATFORM_TLS_T *tls);
extern void platform_tls_destroy(PLATFORM_TLS_T tls);
extern void platform_tls_set(PLATFORM_TLS_T tls, void *v);
extern void *platform_tls_get(PLATFORM_TLS_T tls);
extern void* platform_tls_get_check(PLATFORM_TLS_T tls);
extern void platform_tls_remove(PLATFORM_TLS_T tls);
#endif

View File

@@ -0,0 +1,612 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define VCOS_LOG_CATEGORY (&khrn_client_log)
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_check_types.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/egl/egl_client_config.h"
#include "interface/khronos/glxx/glxx_client.h"
#if defined(V3D_LEAN)
#include "interface/khronos/common/khrn_int_misc_impl.h"
#endif
#if EGL_KHR_sync
#include "interface/khronos/ext/egl_khr_sync_client.h"
#endif
#if EGL_BRCM_perf_monitor
#include "interface/khronos/ext/egl_brcm_perf_monitor_client.h"
#endif
#if EGL_BRCM_driver_monitor
#include "interface/khronos/ext/egl_brcm_driver_monitor_client.h"
#endif
#ifdef RPC_LIBRARY
#include "middleware/dlloader/dlfcn.h"
#include "applications/vmcs/khronos/khronos_server.h"
#endif
VCOS_LOG_CAT_T khrn_client_log = VCOS_LOG_INIT("khrn_client", VCOS_LOG_WARN);
/*
void client_try_unload_server(CLIENT_PROCESS_STATE_T *process)
Preconditions:
-
Postconditions:
-
Invariants preserved:
-
Invariants used:
-
*/
void client_try_unload_server(CLIENT_PROCESS_STATE_T *process)
{
if (/* some context is current */
(process->context_current_count != 0) ||
/* egl is initialised */
process->inited) {
return;
}
/*
Prompt the server to unload Khronos VLL if it can,
and wait until it is done
*/
#ifdef RPC_LIBRARY //TODO: not thread safe
if (process->connected) {
const KHRONOS_FUNC_TABLE_T *func_table;
func_table = khronos_server_lock_func_table(client_library_get_connection());
if (func_table != NULL)
{
func_table->khrn_misc_try_unload_impl();
khronos_server_disconnect();
}
khronos_server_unlock_func_table();
process->connected = false;
}
#else
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
RPC_INT_RES(RPC_CALL0_RES(khrn_misc_try_unload_impl, thread, KHRNMISCTRYUNLOAD_ID)); // return unimportant - read is just to cause blocking
}
#endif
}
/*
void client_process_state_init(CLIENT_PROCESS_STATE_T *state)
Implementation notes:
Does nothing if already initialised.
Preconditions:
process is a valid pointer
Thread owns EGL lock
client_process_state_term must be called at some point after calling this function if we return true.
Postconditions:
Either:
- an error occurred and false is returned, or
- process->inited is true
Invariants preserved:
All invariants on CLIENT_PROCESS_STATE_T
(CLIENT_PROCESS_STATE_INITED_SANITY)
Invariants used:
-
*/
bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
{
if (!process->inited) {
if (!khrn_pointer_map_init(&process->contexts, 64))
return false;
if (!khrn_pointer_map_init(&process->surfaces, 64))
{
khrn_pointer_map_term(&process->contexts);
return false;
}
if (!khrn_pointer_map_init(&process->windows, 64))
{
khrn_pointer_map_term(&process->contexts);
khrn_pointer_map_term(&process->surfaces);
return false;
}
#if EGL_KHR_sync
if (!khrn_pointer_map_init(&process->syncs, 64))
{
khrn_pointer_map_term(&process->contexts);
khrn_pointer_map_term(&process->surfaces);
khrn_pointer_map_term(&process->windows);
return false;
}
#endif
#if EGL_BRCM_global_image && EGL_KHR_image
khrn_global_image_map_init(&process->global_image_egl_images, 8);
#endif
process->next_surface = 1;
process->next_context = 1;
#if EGL_KHR_sync
process->next_sync = 0x80000001;
#endif
#if EGL_BRCM_global_image && EGL_KHR_image
process->next_global_image_egl_image = 1 << 31;
#endif
#if EGL_BRCM_perf_monitor
process->perf_monitor_inited = false;
#endif
#ifdef RPC_LIBRARY
if (!process->connected) {
process->khrn_connection.make_current_func = client_library_send_make_current;
khronos_server_lock_func_table(&process->khrn_connection);
khronos_server_connect(&process->khrn_connection);
khronos_server_unlock_func_table();
RPC_CALL0(khrn_misc_startup_impl, NULL, no_id);
process->connected = true;
}
#endif
process->inited = true;
}
#ifndef ABSTRACT_PLATFORM
#if defined(ANDROID) && !defined (ANDROID_HWCOMPOSER)
egl_config_install_configs(1); // T-format configs
#else
egl_config_install_configs(0); // RSO configs
#endif
#endif
return true;
}
#include "interface/khronos/common/khrn_client_cr.c"
/*
void client_process_state_term(CLIENT_PROCESS_STATE_T *process)
Implementation notes:
Does nothing if already terminated.
Preconditions:
process is a valid pointer
Thread owns EGL lock
Postconditions:
process->inited is false.
Invariants preserved:
(EGL_CONTEXT_IS_DESTROYED)
(CLIENT_PROCESS_STATE_INITED_SANITY)
Invariants used:
-
*/
void client_process_state_term(CLIENT_PROCESS_STATE_T *process)
{
if (process->inited) {
khrn_pointer_map_iterate(&process->contexts, callback_destroy_context, NULL);
khrn_pointer_map_term(&process->contexts);
khrn_pointer_map_iterate(&process->surfaces, callback_destroy_surface, NULL);
khrn_pointer_map_term(&process->surfaces);
khrn_pointer_map_term(&process->windows);
#if EGL_KHR_sync
egl_sync_destroy_all(&process->syncs);
khrn_pointer_map_term(&process->syncs);
#endif
#if EGL_BRCM_global_image && EGL_KHR_image
khrn_global_image_map_term(&process->global_image_egl_images);
#endif
#if EGL_BRCM_perf_monitor
egl_perf_monitor_term(process);
#endif
#if EGL_BRCM_driver_monitor
egl_driver_monitor_term(process);
#endif
process->inited = false;
}
}
CLIENT_PROCESS_STATE_T client_process_state = {
#ifdef RPC_LIBRARY
false, /* not connected */
#endif
0, /* nothing current */
false}; /* not inited */
void client_thread_state_init(CLIENT_THREAD_STATE_T *state)
{
state->error = EGL_SUCCESS;
state->bound_api = EGL_OPENGL_ES_API;
state->opengl.context = 0;
state->opengl.draw = 0;
state->opengl.read = 0;
state->openvg.context = 0;
state->openvg.draw = 0;
state->openvg.read = 0;
state->high_priority = false;
state->merge_pos = 0;
state->merge_end = 0;
state->glgeterror_hack = 0;
state->async_error_notification = false;
}
void client_thread_state_term(CLIENT_THREAD_STATE_T *state)
{
// TODO: termination
platform_term_rpc( state );
}
EGL_CONTEXT_T *client_egl_get_context(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLContext ctx)
{
EGL_CONTEXT_T *context = (EGL_CONTEXT_T *)khrn_pointer_map_lookup(&process->contexts, (uint32_t)(size_t)ctx);
vcos_assert(!context || !context->is_destroyed);
if (!context)
thread->error = EGL_BAD_CONTEXT;
return context;
}
EGL_SURFACE_T *client_egl_get_surface(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLSurface surf)
{
EGL_SURFACE_T *surface = (EGL_SURFACE_T *)khrn_pointer_map_lookup(&process->surfaces, (uint32_t)(size_t)surf);
vcos_assert (!surface || !surface->is_destroyed);
if (!surface)
thread->error = EGL_BAD_SURFACE;
#if EGL_KHR_lock_surface
if (surface && surface->is_locked) {
thread->error = EGL_BAD_ACCESS;
surface = NULL;
}
#endif
return surface;
}
/*
We don't actually insist that the surface is locked. But unlike client_egl_get_surface, we don't throw an
error if it isn't.
*/
EGL_SURFACE_T *client_egl_get_locked_surface(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLSurface surf)
{
EGL_SURFACE_T *surface = (EGL_SURFACE_T *)khrn_pointer_map_lookup(&process->surfaces, (uint32_t)(size_t)surf);
vcos_assert (!surface || !surface->is_destroyed);
if (!surface)
thread->error = EGL_BAD_SURFACE;
return surface;
}
/*
* just return if we've seen window before
*/
EGLNativeWindowType client_egl_get_window(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLNativeWindowType window)
{
EGLNativeWindowType win = (EGLNativeWindowType)khrn_pointer_map_lookup(&process->windows, (uint32_t)(size_t)window);
return win;
}
static uint32_t convert_gltype(EGL_CONTEXT_TYPE_T type)
{
switch (type) {
case OPENGL_ES_11: return EGL_SERVER_GL11;
case OPENGL_ES_20: return EGL_SERVER_GL20;
default: UNREACHABLE(); return 0;
}
}
void client_send_make_current(CLIENT_THREAD_STATE_T *thread)
{
uint64_t pid = khronos_platform_get_process_id();
uint32_t gltype = thread->opengl.context ? convert_gltype(thread->opengl.context->type) : 0;
EGL_GL_CONTEXT_ID_T servergl = thread->opengl.context ? thread->opengl.context->servercontext : EGL_SERVER_NO_GL_CONTEXT;
EGL_SURFACE_ID_T servergldraw = thread->opengl.draw ? thread->opengl.draw->serverbuffer : EGL_SERVER_NO_SURFACE;
EGL_SURFACE_ID_T serverglread = thread->opengl.read ? thread->opengl.read->serverbuffer : EGL_SERVER_NO_SURFACE;
EGL_VG_CONTEXT_ID_T servervg = thread->openvg.context ? thread->openvg.context->servercontext : EGL_SERVER_NO_VG_CONTEXT;
EGL_SURFACE_ID_T servervgsurf = thread->openvg.draw ? thread->openvg.draw->serverbuffer : EGL_SERVER_NO_SURFACE;
/*
if the size of this call in the merge buffer changes,
CLIENT_MAKE_CURRENT_SIZE in khrn_client.h should be updated
*/
if (!thread->opengl.context || !thread->opengl.draw)
{
vcos_log_trace("Send null make current %x %x",
(unsigned int)(char *)thread->opengl.context, (unsigned int)(char *)thread->opengl.draw);
}
else
{
vcos_log_trace("Send make current %d[%d %s%s] %d[%d %d%s]",
(int)thread->opengl.context->name,
thread->opengl.context->servercontext,
thread->opengl.context->is_current ? " C" : "",
thread->opengl.context->is_destroyed ? " D" : "",
(int)thread->opengl.draw->name,
thread->opengl.draw->serverbuffer,
thread->opengl.draw->context_binding_count,
thread->opengl.draw->is_destroyed ? " D" : "");
}
RPC_CALL8_MAKECURRENT(eglIntMakeCurrent_impl,
thread,
EGLINTMAKECURRENT_ID,
RPC_UINT((uint32_t)pid),
RPC_UINT((uint32_t)(pid >> 32)),
RPC_UINT(gltype),
RPC_UINT(servergl),
RPC_UINT(servergldraw),
RPC_UINT(serverglread),
RPC_UINT(servervg),
RPC_UINT(servervgsurf));
}
PLATFORM_TLS_T client_tls;
PLATFORM_MUTEX_T client_mutex;
#ifdef CLIENT_THREAD_IS_PROCESS
PLATFORM_TLS_T client_tls_process;
PLATFORM_TLS_T client_tls_mutex;
#endif
bool client_process_attach()
{
KHR_STATUS_T status;
status = platform_tls_create(&client_tls);
if (status != KHR_SUCCESS) {
return false;
}
#ifdef CLIENT_THREAD_IS_PROCESS
status = platform_tls_create(&client_tls_process);
if (status != KHR_SUCCESS) {
return false;
}
status = platform_tls_create(&client_tls_mutex);
if (status != KHR_SUCCESS) {
return false;
}
#endif
status = platform_mutex_create(&client_mutex);
if (status != KHR_SUCCESS) {
platform_tls_destroy(client_tls);
return false;
}
if (!RPC_INIT()) {
platform_mutex_destroy(&client_mutex);
platform_tls_destroy(client_tls);
return false;
}
return true;
}
bool client_thread_attach()
{
CLIENT_THREAD_STATE_T *state = (CLIENT_THREAD_STATE_T *)khrn_platform_malloc(sizeof(CLIENT_THREAD_STATE_T), "CLIENT_THREAD_STATE_T");
if (!state)
return false;
client_thread_state_init(state);
platform_tls_set(client_tls, state);
#ifdef CLIENT_THREAD_IS_PROCESS
{ //add mutex into thread's tls
KHR_STATUS_T status;
PLATFORM_MUTEX_T *local_mutex = (PLATFORM_MUTEX_T*)vcos_tls_get(client_tls_mutex);
if (!local_mutex)
{
local_mutex = (PLATFORM_MUTEX_T*)khrn_platform_malloc(sizeof(PLATFORM_MUTEX_T),"thread mutex");
if (!local_mutex)
return false;
status = platform_mutex_create(local_mutex);
if (status != KHR_SUCCESS) {
khrn_platform_free(local_mutex);
return false;
}
vcos_tls_set(client_tls_mutex,local_mutex);
}
}
#endif
#ifndef RPC_LIBRARY //TODO
client_send_make_current(state);
#endif
return true;
}
void client_thread_detach(void *dummy)
{
CLIENT_THREAD_STATE_T *state = CLIENT_GET_THREAD_STATE();
UNUSED(dummy);
platform_tls_remove(client_tls);
client_thread_state_term(state);
khrn_platform_free(state);
platform_maybe_free_process();
#ifdef CLIENT_THREAD_IS_PROCESS
{
CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
khrn_platform_free(process);
platform_tls_remove(client_tls_process);
}
{
PLATFORM_MUTEX_T *local_mutex = (PLATFORM_MUTEX_T*)vcos_tls_get(client_tls_mutex);
vcos_assert(local_mutex);
platform_mutex_destroy(local_mutex);
khrn_platform_free(local_mutex);
platform_tls_remove(client_tls_mutex);
}
#endif
}
void client_process_detach()
{
RPC_TERM();
platform_tls_destroy(client_tls);
platform_mutex_destroy(&client_mutex);
#ifdef CLIENT_THREAD_IS_PROCESS
platform_tls_destroy(client_tls_process);
#endif
}
#ifdef RPC_LIBRARY
KHRONOS_SERVER_CONNECTION_T *client_library_get_connection(void)
{
return &client_process_state.khrn_connection;
}
#endif
#if defined(RPC_LIBRARY) || defined(RPC_DIRECT_MULTI)
void client_library_send_make_current(const KHRONOS_FUNC_TABLE_T *func_table)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (thread->opengl.context || thread->openvg.context)
{
uint64_t pid = khronos_platform_get_process_id();
uint32_t gltype = thread->opengl.context ? convert_gltype(thread->opengl.context->type) : 0;
EGL_GL_CONTEXT_ID_T servergl = thread->opengl.context ? thread->opengl.context->servercontext : EGL_SERVER_NO_GL_CONTEXT;
EGL_SURFACE_ID_T servergldraw = thread->opengl.draw ? thread->opengl.draw->serverbuffer : EGL_SERVER_NO_SURFACE;
EGL_SURFACE_ID_T serverglread = thread->opengl.read ? thread->opengl.read->serverbuffer : EGL_SERVER_NO_SURFACE;
EGL_VG_CONTEXT_ID_T servervg = thread->openvg.context ? thread->openvg.context->servercontext : EGL_SERVER_NO_VG_CONTEXT;
EGL_SURFACE_ID_T servervgsurf = thread->openvg.draw ? thread->openvg.draw->serverbuffer : EGL_SERVER_NO_SURFACE;
/*
if the size of this call in the merge buffer changes,
CLIENT_MAKE_CURRENT_SIZE in khrn_client.h should be updated
*/
func_table->eglIntMakeCurrent_impl(
(uint32_t)pid,
(uint32_t)(pid >> 32),
gltype,
servergl,
servergldraw,
serverglread,
servervg,
servervgsurf);
}
}
#endif
#ifdef GL_GET_ERROR_ASYNC
static void callback_set_error(KHRN_POINTER_MAP_T *map, uint32_t key, void *value, void *data)
{
EGL_CONTEXT_T *context = (EGL_CONTEXT_T *)value;
UNUSED(map);
UNUSED_NDEBUG(key);
vcos_assert( context != NULL );
vcos_assert((uintptr_t)key == (uintptr_t)context->name);
if (context->servercontext == *((uint32_t *)data)){
CLIENT_THREAD_STATE_T *thread = context->thread;
/* todo: VG */
if (thread && IS_OPENGLES_11_OR_20(thread)) {
vcos_log_error("GL OOM context %d", context->servercontext);
glxx_set_error(GLXX_GET_CLIENT_STATE(thread), GL_OUT_OF_MEMORY);
}
}
}
void client_set_error(uint32_t server_context_name)
{
CLIENT_PROCESS_STATE_T *process;
CLIENT_LOCK();
process = CLIENT_GET_PROCESS_STATE();
khrn_pointer_map_iterate(&process->contexts, callback_set_error, &server_context_name);
CLIENT_UNLOCK();
}
#endif

View File

@@ -0,0 +1,485 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_H
#define KHRN_CLIENT_H
typedef struct CLIENT_PROCESS_STATE CLIENT_PROCESS_STATE_T;
typedef struct CLIENT_THREAD_STATE CLIENT_THREAD_STATE_T;
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/egl/egl_client_context.h"
#include "interface/khronos/egl/egl_client_surface.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/common/khrn_client_pointermap.h"
#ifdef RPC_LIBRARY
#include "middleware/khronos/common/khrn_misc.h"
#include "applications/vmcs/khronos/khronos_server.h"
#elif defined(RPC_DIRECT_MULTI)
#include "middleware/khronos/common/khrn_misc.h"
#endif
/* must be after EGL/eglext.h */
#if EGL_BRCM_global_image && EGL_KHR_image
#include "interface/khronos/common/khrn_client_global_image_map.h"
#endif
extern void client_try_unload_server(CLIENT_PROCESS_STATE_T *process);
/*
per-thread state
- EGL error
- EGL bound API
- EGL context and surfaces for each API
- RPC merge buffer
*/
#define MERGE_BUFFER_SIZE 4080
typedef struct {
EGL_CONTEXT_T *context;
EGL_SURFACE_T *draw;
EGL_SURFACE_T *read;
} EGL_CURRENT_T;
struct CLIENT_THREAD_STATE {
/*
error
Invariant:
(CLIENT_THREAD_STATE_ERROR)
error is one of
EGL_SUCCESS
EGL_NOT_INITIALIZED
EGL_BAD_ACCESS
EGL_BAD_ALLOC
EGL_BAD_ATTRIBUTE
EGL_BAD_CONTEXT
EGL_BAD_CONFIG
EGL_BAD_CURRENT SURFACE
EGL_BAD_DISPLAY
EGL_BAD_SURFACE
EGL_BAD_MATCH
EGL_BAD_PARAMETER
EGL_BAD_NATIVE PIXMAP
EGL_BAD_NATIVE WINDOW
EGL_CONTEXT_LOST
*/
EGLint error;
EGLenum bound_api;
/*
handles to current display, context and surfaces for each API
Availability:
Thread owns EGL lock
*/
EGL_CURRENT_T opengl;
EGL_CURRENT_T openvg;
/*
rpc stuff
*/
bool high_priority;
uint8_t merge_buffer[MERGE_BUFFER_SIZE];
uint32_t merge_pos;
uint32_t merge_end;
/* Try to reduce impact of repeated consecutive glGetError() calls */
int32_t glgeterror_hack;
bool async_error_notification;
};
extern void client_thread_state_init(CLIENT_THREAD_STATE_T *state);
extern void client_thread_state_term(CLIENT_THREAD_STATE_T *state);
extern PLATFORM_TLS_T client_tls;
/*
CLIENT_GET_THREAD_STATE
Implementation notes:
TODO: make sure this gets code-reviewed
Preconditions:
-
Postconditions:
Result is a valid pointer to a thread-local CLIENT_THREAD_STATE_T structure.
Invariants preserved:
-
Invariants used:
-
*/
static INLINE CLIENT_THREAD_STATE_T *CLIENT_GET_THREAD_STATE(void)
{
CLIENT_THREAD_STATE_T *tls;
tls = (CLIENT_THREAD_STATE_T *)platform_tls_get(client_tls);
if( tls && tls->glgeterror_hack ) {
tls->glgeterror_hack--;
}
return tls;
}
static INLINE CLIENT_THREAD_STATE_T *CLIENT_GET_CHECK_THREAD_STATE(void)
{
return (CLIENT_THREAD_STATE_T *)platform_tls_get_check(client_tls);
}
/*
per-process state
- EGL initialization stage
- EGL contexts and surfaces
- EGL counters
*/
struct CLIENT_PROCESS_STATE {
#ifdef RPC_LIBRARY
/*
called khronos_server_connect? this is valid even if !inited
*/
bool connected;
#endif
/*
number of current contexts across all threads in this process. this is valid
even if !inited
*/
uint32_t context_current_count;
/*
inited
Specifies whether the structure has been initialised and all of the other members are valid.
inited is true between eglInitialise/eglTerminate. threads can still have
things current when !inited
Invariants:
(CLIENT_PROCESS_STATE_INITED_SANITY)
Only client_process_state_init/client_process_state_term modify this value
*/
bool inited;
/*
contexts
A map from context id (EGLContext) to EGL_CONTEXT_T
TODO: use pointers as key rather than integers
Validity: inited is true
Invariants:
(CLIENT_PROCESS_STATE_CONTEXTS)
If id is a key in contexts:
contexts[id].name == id
contexts[id].is_destroyed == false
*/
KHRN_POINTER_MAP_T contexts;
/*
surfaces
A map from context id (EGLContext) to EGL_SURFACE_T
Validity: inited is true
Invariants:
(CLIENT_PROCESS_STATE_SURFACES)
If id is a key in surfaces:
surfaces[id].name == id
surfaces[id].is_destroyed == false
*/
KHRN_POINTER_MAP_T surfaces;
/*
* some platforms (e.g. Android) need to maintain a list of
* known windows
*/
KHRN_POINTER_MAP_T windows;
#if EGL_KHR_sync
/*
syncs
Validity: inited is true
*/
KHRN_POINTER_MAP_T syncs;
#endif
#if EGL_BRCM_global_image && EGL_KHR_image
KHRN_GLOBAL_IMAGE_MAP_T global_image_egl_images;
#endif
/*
next_surface
Implementation notes:
TODO: these could theoretically overflow
Validity: inited is true
Invariant:
(CLIENT_PROCESS_STATE_NEXT_SURFACE)
next_surface is greater than every key in surfaces
next_surface >= 1
*/
uint32_t next_surface;
/*
next_context
Validity: inited is true
*/
uint32_t next_context;
#if EGL_KHR_sync
/*
next_sync
Validity: inited is true
*/
uint32_t next_sync;
#endif
#if EGL_BRCM_global_image && EGL_KHR_image
uint32_t next_global_image_egl_image;
#endif
#if EGL_BRCM_perf_monitor
/*
perf_monitor_inited
Validity: inited is true
*/
bool perf_monitor_inited;
#endif
#if EGL_BRCM_driver_monitor
/*
driver_monitor_inited
Validity: inited is true
*/
bool driver_monitor_inited;
#endif
#ifdef RPC_LIBRARY
KHRONOS_SERVER_CONNECTION_T khrn_connection;
#endif
};
extern bool client_process_state_init(CLIENT_PROCESS_STATE_T *process);
extern void client_process_state_term(CLIENT_PROCESS_STATE_T *process);
extern CLIENT_PROCESS_STATE_T client_process_state;
/*
CLIENT_GET_PROCESS_STATE()
Returns the process-global CLIENT_PROCESS_STATE_T object.
*/
#ifdef CLIENT_THREAD_IS_PROCESS
extern PLATFORM_TLS_T client_tls_process;
extern PLATFORM_TLS_T client_tls_mutex;
extern void *platform_tls_get_process(PLATFORM_TLS_T tls);
#endif
static INLINE CLIENT_PROCESS_STATE_T *CLIENT_GET_PROCESS_STATE(void)
{
#ifdef CLIENT_THREAD_IS_PROCESS
//each thread has its own client_process_state
return (CLIENT_PROCESS_STATE_T *)platform_tls_get_process(client_tls_process);
#else
return &client_process_state;
#endif
}
/*
exposed bits of EGL
*/
CLIENT_PROCESS_STATE_T *client_egl_get_process_state(CLIENT_THREAD_STATE_T *thread, EGLDisplay dpy, EGLBoolean check_inited);
EGL_CONTEXT_T *client_egl_get_context(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLContext ctx);
EGL_SURFACE_T *client_egl_get_surface(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLSurface surf);
EGL_SURFACE_T *client_egl_get_locked_surface(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLSurface surf);
EGLNativeWindowType client_egl_get_window(CLIENT_THREAD_STATE_T *thread, CLIENT_PROCESS_STATE_T *process, EGLNativeWindowType window);
/*
client state
*/
#define CLIENT_MAKE_CURRENT_SIZE 36 /* RPC_CALL8 */
extern void client_send_make_current(CLIENT_THREAD_STATE_T *thread);
extern void client_set_error(uint32_t server_context_name);
/*
big giant lock
*/
extern PLATFORM_MUTEX_T client_mutex;
/*
CLIENT_LOCK()
Acquires EGL lock.
Implementation notes:
TODO make sure this gets reviewed
Preconditions:
TODO: check mutex hierarchy methodology
Mutex: >(MUTEX_EGL_LOCK)
Is being called from a function which _always_ subsequently calls CLIENT_UNLOCK()
Postconditions:
Mutex: (MUTEX_EGL_LOCK)
Thread owns EGL lock
*/
static INLINE void CLIENT_LOCK(void)
{
platform_client_lock();
}
/*
CLIENT_UNLOCK()
Releases EGL lock.
Implementation notes:
TODO make sure this gets reviewed
Preconditions:
Mutex: (MUTEX_EGL_LOCK)
Thread owns EGL lock
Is being called from a function which has _always_ previously called CLIENT_LOCK()
Postconditions:
Mutex: >(MUTEX_EGL_LOCK)
*/
static INLINE void CLIENT_UNLOCK(void)
{
platform_client_release();
}
/*
bool CLIENT_LOCK_AND_GET_STATES(EGLDisplay dpy, CLIENT_THREAD_STATE_T **thread, CLIENT_PROCESS_STATE_T **process)
Try to acquire EGL lock and get thread and process state.
Implementation notes:
TODO make sure this gets reviewed
Preconditions:
thread is a valid pointer to a thread*
process is a valid pointer to a process*
Mutex: >(MUTEX_EGL_LOCK)
Is being called from a function which calls CLIENT_UNLOCK() if we return true
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED EGL is not initialized for the specified display.
if more than one condition holds, the first error is generated.
Either:
Mutex: (MUTEX_EGL_LOCK)
Thread owns EGL lock
result is true
Or:
Nothing changes
result is false
*/
static INLINE bool CLIENT_LOCK_AND_GET_STATES(EGLDisplay dpy, CLIENT_THREAD_STATE_T **thread, CLIENT_PROCESS_STATE_T **process)
{
*thread = CLIENT_GET_THREAD_STATE();
CLIENT_LOCK();
*process = client_egl_get_process_state(*thread, dpy, EGL_TRUE);
if (*process != NULL)
return true;
else
{
CLIENT_UNLOCK();
return false;
}
}
/*
process and thread attach/detach hooks
*/
#ifdef __cplusplus
extern "C" {
#endif
extern bool client_process_attach(void);
extern bool client_thread_attach(void);
extern void client_thread_detach(void *dummy);
extern void client_process_detach(void);
#ifdef RPC_LIBRARY
extern KHRONOS_SERVER_CONNECTION_T *client_library_get_connection(void);
extern void client_library_send_make_current(const KHRONOS_FUNC_TABLE_T *func_table);
#elif defined(RPC_DIRECT_MULTI)
extern void client_library_send_make_current(const KHRONOS_FUNC_TABLE_T *func_table);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,382 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_cache.h"
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/common/khrn_int_hash.h"
#include "interface/khronos/common/khrn_int_util.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/glxx_int_impl.h"
#endif
#include <assert.h>
#if defined(SIMPENROSE)
#include "tools/v3d/simpenrose/simpenrose.h"
#endif
static void link_insert(CACHE_LINK_T *link, CACHE_LINK_T *prev, CACHE_LINK_T *next)
{
vcos_assert(prev->next == next);
vcos_assert(next->prev == prev);
link->prev = prev;
link->next = next;
prev->next = link;
next->prev = link;
}
static void link_remove(CACHE_LINK_T *link)
{
link->next->prev = link->prev;
link->prev->next = link->next;
}
static void tree_init(uint8_t *tree, int depth)
{
int i;
tree[0] = depth + 1;
for (i = 1; i < 1 << depth; i++)
tree[i] = tree[i >> 1] - 1;
}
static int heap_avail(KHRN_CACHE_T *cache, int size)
{
return cache->tree && cache->tree[1] >= size;
}
static int heap_alloc(KHRN_CACHE_T *cache, int size)
{
int node, fixup;
int i;
assert(heap_avail(cache, size));
node = 1;
for (i = 0; i < cache->client_depth - size; i++) {
node <<= 1;
if (cache->tree[node + 1] >= size && (cache->tree[node] < size || cache->tree[node] > cache->tree[node + 1]))
node++;
}
cache->tree[node] = 0;
for (fixup = node; cache->tree[fixup ^ 1] < cache->tree [fixup >> 1]; fixup >>= 1)
cache->tree[fixup >> 1] = _max(cache->tree[fixup], cache->tree[fixup ^ 1]);
return node * (1 << (size - 1)) - (1 << (cache->client_depth - 1));
}
static void heap_free(KHRN_CACHE_T *cache, int block)
{
int node = block + (1 << (cache->client_depth - 1));
int reset = 1;
while (cache->tree[node] > 0) {
node >>= 1;
reset++;
}
cache->tree[node] = reset;
while (cache->tree[node] == cache->tree[node ^ 1]) {
node >>= 1;
cache->tree[node] = cache->tree[node] + 1;
}
while (cache->tree[node] > cache->tree[node >> 1]) {
cache->tree[node >> 1] = cache->tree[node];
node >>= 1;
}
}
static uint32_t hash(const void *data, int len, int sig)
{
int hash;
// if (len > 256) // TODO: turn this on later
// len = 256;
if (!((size_t)data & 3) && !(len & 3))
hash = khrn_hashword((uint32_t *)data, len >> 2, 0);
else
hash = khrn_hashlittle(data, len, 0);
return (hash & ~0xf) | sig;
}
int khrn_cache_init(KHRN_CACHE_T *cache)
{
cache->tree = NULL;
cache->data = NULL;
cache->client_depth = 0;
cache->server_depth = 0;
cache->start.prev = NULL;
cache->start.next = &cache->end;
cache->end.prev = &cache->start;
cache->end.next = NULL;
return khrn_pointer_map_init(&cache->map, 64);
}
void khrn_cache_term(KHRN_CACHE_T *cache)
{
khrn_platform_free(cache->tree);
khrn_platform_free(cache->data);
khrn_pointer_map_term(&cache->map);
}
static void send_create(CLIENT_THREAD_STATE_T *thread, int base)
{
RPC_CALL1(glintCacheCreate_impl,
thread,
GLINTCACHECREATE_ID,
RPC_UINT(base));
}
static void send_delete(CLIENT_THREAD_STATE_T *thread, int base)
{
RPC_CALL1(glintCacheDelete_impl,
thread,
GLINTCACHEDELETE_ID,
RPC_UINT(base));
}
static int send_grow(CLIENT_THREAD_STATE_T *thread)
{
return RPC_BOOLEAN_RES(RPC_CALL0_RES(glintCacheGrow_impl,
thread,
GLINTCACHEGROW_ID));
}
static void send_data(CLIENT_THREAD_STATE_T *thread, int base, const void *data, int len)
{
int off = 0;
while (len > 0) {
int chunk = _min(len, MERGE_BUFFER_SIZE-CLIENT_MAKE_CURRENT_SIZE-12-8);
RPC_CALL3_IN_CTRL(glintCacheData_impl,
thread,
GLINTCACHEDATA_ID,
RPC_UINT(base + off),
RPC_SIZEI(chunk),
(char *)data + off,
chunk);
off += chunk;
len -= chunk;
}
}
static void discard(CLIENT_THREAD_STATE_T *thread, KHRN_CACHE_T *cache, CACHE_ENTRY_T *entry)
{
heap_free(cache, (int)((uint8_t *)entry - cache->data) >> CACHE_LOG2_BLOCK_SIZE);
khrn_pointer_map_delete(&cache->map, entry->key);
link_remove(&entry->link);
send_delete(thread, (int)((uint8_t *)entry - cache->data));
}
static void *relocate(void *data, void *user)
{
return (uint8_t *)data - ((uint8_t **)user)[0] + ((uint8_t **)user)[1];
}
static void callback(KHRN_POINTER_MAP_T *map, uint32_t key, void *value, void *user)
{
CACHE_ENTRY_T *entry = (CACHE_ENTRY_T *)value;
entry->link.prev = (CACHE_LINK_T *)relocate(entry->link.prev, user);
entry->link.next = (CACHE_LINK_T *)relocate(entry->link.next, user);
// Coverity has rightly pointed out that the allocations done in the next codeline can fail
// verify will only assert the code in debug mode. Use in release mode stays the same as before...
verify(khrn_pointer_map_insert(map, key, relocate(value, user)));
}
static int grow(CLIENT_THREAD_STATE_T *thread, KHRN_CACHE_T *cache)
{
/*
try to grow the server cache
*/
uint8_t *tree;
uint8_t *data;
int i;
if (cache->server_depth == cache->client_depth) {
if (cache->server_depth < CACHE_MAX_DEPTH && send_grow(thread))
cache->server_depth++;
else
return 0;
}
tree = (uint8_t *)khrn_platform_malloc(1 << (cache->client_depth + 1), "KHRN_CACHE_T.tree");
data = (uint8_t *)khrn_platform_malloc(1 << (cache->client_depth + CACHE_LOG2_BLOCK_SIZE), "KHRN_CACHE_T.data");
if (!tree || !data) {
khrn_platform_free(tree);
khrn_platform_free(data);
return 0;
}
/*
set up new tree structure
*/
tree_init(tree, cache->client_depth + 1);
if (cache->client_depth) {
for (i = 1; i < 1 << cache->client_depth; i++)
tree[i ^ 3 << _msb(i)] = cache->tree[i];
tree[1] = tree[3] + (tree[2] == tree[3]);
}
/*
relocate pointermap and linked list pointers
*/
{
uint8_t *user[2];
user[0] = cache->data;
user[1] = data;
khrn_pointer_map_iterate(&cache->map, callback, user);
cache->start.next->prev = &cache->start;
if (cache->start.next != &cache->end)
cache->start.next = (CACHE_LINK_T *)relocate(cache->start.next, user);
cache->end.prev->next = &cache->end;
if (cache->end.prev != &cache->start)
cache->end.prev = (CACHE_LINK_T *)relocate(cache->end.prev, user);
}
/*
set up new data block
*/
if (cache->data)
platform_memcpy(data, cache->data, 1 << (cache->client_depth + CACHE_LOG2_BLOCK_SIZE - 1));
/*
free old blocks, update structure
*/
khrn_platform_free(cache->tree);
khrn_platform_free(cache->data);
cache->tree = tree;
cache->data = data;
cache->client_depth++;
return 1;
}
#ifdef SIMPENROSE_RECORD_OUTPUT
static bool xxx_first = true;
#endif
int khrn_cache_lookup(CLIENT_THREAD_STATE_T *thread, KHRN_CACHE_T *cache, const void *data, int len, int sig)
{
int key = hash(data, len, sig);
CACHE_ENTRY_T *entry = (CACHE_ENTRY_T *)khrn_pointer_map_lookup(&cache->map, key);
#ifdef SIMPENROSE_RECORD_OUTPUT
if (xxx_first)
{
/* Cannot grow cache while things are locked for recording. So grow it now as much as we think we'll need */
uint32_t i;
xxx_first = false;
for (i = 0; i < 15; i++)
grow(thread, cache);
}
#endif
if (entry && entry->len >= len && !memcmp(entry->data, data, len)) {
/*
move link to end of discard queue
*/
link_remove(&entry->link);
link_insert(&entry->link, cache->end.prev, &cache->end);
} else {
int size = _max(_msb(len + sizeof(CACHE_ENTRY_T) - 1) + 2 - CACHE_LOG2_BLOCK_SIZE, 1);
int block;
CACHE_LINK_T *link;
if (entry)
discard(thread, cache, entry);
while (!heap_avail(cache, size) && grow(thread, cache));
for (link = cache->start.next; link != &cache->end && !heap_avail(cache, size); link = link->next)
discard(thread, cache, (CACHE_ENTRY_T *)link);
if (!heap_avail(cache, size))
return -1;
block = heap_alloc(cache, size);
entry = (CACHE_ENTRY_T *)(cache->data + (block << CACHE_LOG2_BLOCK_SIZE));
entry->len = len;
entry->key = key;
platform_memcpy(entry->data, data, len);
if (!khrn_pointer_map_insert(&cache->map, key, entry)) {
heap_free(cache, block);
return -1;
}
link_insert(&entry->link, cache->end.prev, &cache->end);
send_create(thread, (int)((uint8_t *)entry - cache->data));
send_data(thread, (int)(entry->data - cache->data), data, len);
}
return (int)((uint8_t *)entry - cache->data);
}
int khrn_cache_get_entries(KHRN_CACHE_T *cache)
{
return cache->map.entries;
}

View File

@@ -0,0 +1,92 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_CACHE_H
#define KHRN_CLIENT_CACHE_H
//#define WORKAROUND_HW2551 // define to pad header structure to 32 bytes
#include "interface/khronos/common/khrn_client_pointermap.h"
#include "interface/khronos/common/khrn_client.h"
typedef struct CACHE_LINK_S {
struct CACHE_LINK_S *prev;
struct CACHE_LINK_S *next;
} CACHE_LINK_T;
typedef struct {
CACHE_LINK_T link;
int len;
int key;
#ifdef WORKAROUND_HW2551
uint8_t pad[16];
#endif
//on the server side
//we store a KHRN_INTERLOCK_T in the
//same space as this struct
uint8_t pad_for_interlock[24];
uint8_t data[1];
} CACHE_ENTRY_T;
typedef struct {
uint8_t *tree;
uint8_t *data;
int client_depth;
int server_depth;
CACHE_LINK_T start;
CACHE_LINK_T end;
KHRN_POINTER_MAP_T map;
} KHRN_CACHE_T;
#define CACHE_LOG2_BLOCK_SIZE 6
#define CACHE_MAX_DEPTH 16
#define CACHE_SIG_ATTRIB_0 0
#define CACHE_SIG_ATTRIB_1 1
#define CACHE_SIG_ATTRIB_2 2
#define CACHE_SIG_ATTRIB_3 3
#define CACHE_SIG_ATTRIB_4 4
#define CACHE_SIG_ATTRIB_5 5
#define CACHE_SIG_ATTRIB_6 6
#define CACHE_SIG_ATTRIB_7 7
#define CACHE_SIG_INDEX 8
extern int khrn_cache_init(KHRN_CACHE_T *cache);
extern void khrn_cache_term(KHRN_CACHE_T *cache);
extern int khrn_cache_lookup(CLIENT_THREAD_STATE_T *thread, KHRN_CACHE_T *cache, const void *data, int len, int sig);
extern int khrn_cache_get_entries(KHRN_CACHE_T *cache);
#endif

View File

@@ -0,0 +1,87 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_CHECK_TYPES_H
#define KHRN_CLIENT_CHECK_TYPES_H
#include "interface/khronos/common/khrn_int_util.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/VG/openvg.h"
/*
egl types
*/
vcos_static_assert(sizeof(EGLint) == 4);
vcos_static_assert(sizeof(EGLBoolean) == 4);
vcos_static_assert(sizeof(EGLenum) == 4);
vcos_static_assert(sizeof(EGLConfig) == 4);
vcos_static_assert(sizeof(EGLContext) == 4);
vcos_static_assert(sizeof(EGLDisplay) == 4);
vcos_static_assert(sizeof(EGLSurface) == 4);
vcos_static_assert(sizeof(EGLClientBuffer) == 4);
vcos_static_assert(sizeof(NativeDisplayType) == 4);
vcos_static_assert(sizeof(NativePixmapType) == 4);
vcos_static_assert(sizeof(NativeWindowType) == 4);
/*
gl types
*/
vcos_static_assert(sizeof(GLenum) == 4);
vcos_static_assert(sizeof(GLboolean) == 1);
vcos_static_assert(sizeof(GLbitfield) == 4);
vcos_static_assert(sizeof(GLbyte) == 1);
vcos_static_assert(sizeof(GLshort) == 2);
vcos_static_assert(sizeof(GLint) == 4);
vcos_static_assert(sizeof(GLsizei) == 4);
vcos_static_assert(sizeof(GLubyte) == 1);
vcos_static_assert(sizeof(GLushort) == 2);
vcos_static_assert(sizeof(GLuint) == 4);
vcos_static_assert(sizeof(GLfloat) == 4);
vcos_static_assert(sizeof(GLclampf) == 4);
vcos_static_assert(sizeof(GLfixed) == 4);
vcos_static_assert(sizeof(GLclampx) == 4);
vcos_static_assert(sizeof(GLintptr) == 4);
vcos_static_assert(sizeof(GLsizeiptr) == 4);
/*
vg types
*/
vcos_static_assert(sizeof(VGfloat) == 4);
vcos_static_assert(sizeof(VGbyte) == 1);
vcos_static_assert(sizeof(VGubyte) == 1);
vcos_static_assert(sizeof(VGshort) == 2);
vcos_static_assert(sizeof(VGint) == 4);
vcos_static_assert(sizeof(VGuint) == 4);
vcos_static_assert(sizeof(VGbitfield) == 4);
vcos_static_assert(sizeof(VGboolean) == 4);
#endif

View File

@@ -0,0 +1,140 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
static void callback_destroy_context(KHRN_POINTER_MAP_T *map, uint32_t key, void *value, void *data)
{
EGL_CONTEXT_T *context = (EGL_CONTEXT_T *)value;
UNUSED(map);
UNUSED(data);
UNUSED_NDEBUG(key);
vcos_assert( context != NULL );
vcos_assert((uintptr_t)key == (uintptr_t)context->name);
vcos_assert(!context->is_destroyed);
context->is_destroyed = true;
egl_context_maybe_free(context);
}
/*
void callback_destroy_surface(KHRN_POINTER_MAP_T *map, uint32_t key, void *value, void *data)
Implementation notes:
Passed as a callback to khrn_pointer_map_iterate.
Preconditions:
Thread owns EGL lock
map is the CLIENT_PROCESS_STATE_T.surfaces
value is a pointer to a valid EGL_SURFACE_T
key is a key in map
map[key] == value
Postconditions:
Does not alter map
value is a dead pointer (i.e. either a pointer to a freed thing or something we don't hold a reference to)
Invariants preserved:
(EGL_SURFACE_IS_DESTROYED)
Invariants used:
(CLIENT_PROCESS_STATE_SURFACES)
(EGL_SURFACE_BINDING_COUNT)
*/
static void callback_destroy_surface(KHRN_POINTER_MAP_T *map, uint32_t key, void *value, void *data)
{
EGL_SURFACE_T *surface = (EGL_SURFACE_T *)value;
UNUSED(map);
UNUSED(data);
UNUSED_NDEBUG(key);
vcos_assert( surface != NULL );
vcos_assert((uintptr_t)key == (uintptr_t)surface->name);
surface->is_destroyed = true;
egl_surface_maybe_free(surface);
}
/*
CLIENT_PROCESS_STATE_T *client_egl_get_process_state(CLIENT_THREAD_STATE_T *thread, EGLDisplay dpy, EGLBoolean check_inited)
Returns the process-global CLIENT_PROCESS_STATE_T object. If check_inited is true, also insists that the process state
is inited.
Implementation notes:
-
Preconditions:
thread is a valid pointer
Thread owns EGL lock
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED check_inited is true and EGL is not initialized for the specified display.
if more than one condition holds, the first error is generated.
If error, NULL is returned. Otherwise a pointer is returned which is valid for the lifetime of the process.
Invariants preserved:
-
Invariants used:
-
*/
CLIENT_PROCESS_STATE_T *client_egl_get_process_state(CLIENT_THREAD_STATE_T *thread, EGLDisplay dpy, EGLBoolean check_inited)
{
if ((size_t)dpy == 1) {
CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
if (check_inited && !process->inited) {
thread->error = EGL_NOT_INITIALIZED;
return NULL;
} else
return process;
} else {
thread->error = EGL_BAD_DISPLAY;
return NULL;
}
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#if EGL_BRCM_global_image && EGL_KHR_image
static INLINE void acquire_value(uint64_t value)
{
platform_acquire_global_image((uint32_t)value, (uint32_t)(value >> 32));
}
static INLINE void release_value(uint64_t value)
{
platform_release_global_image((uint32_t)value, (uint32_t)(value >> 32));
}
#define KHRN_GENERIC_MAP_VALUE_NONE ((uint64_t)0)
#define KHRN_GENERIC_MAP_VALUE_DELETED ((uint64_t)-1)
#define KHRN_GENERIC_MAP_ACQUIRE_VALUE acquire_value
#define KHRN_GENERIC_MAP_RELEASE_VALUE release_value
#define KHRN_GENERIC_MAP_ALLOC khrn_platform_malloc
#define KHRN_GENERIC_MAP_FREE khrn_platform_free
#define CLIENT_GLOBAL_IMAGE_MAP_C
#include "interface/khronos/common/khrn_client_global_image_map.h"
#endif

View File

@@ -0,0 +1,47 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_GLOBAL_IMAGE_MAP_H
#define KHRN_CLIENT_GLOBAL_IMAGE_MAP_H
#define khrn_generic_map(X) khrn_global_image_map_##X
#define KHRN_GENERIC_MAP(X) KHRN_GLOBAL_IMAGE_MAP_##X
#define KHRN_GENERIC_MAP_KEY_T uint32_t
#define KHRN_GENERIC_MAP_VALUE_T uint64_t
#ifdef CLIENT_GLOBAL_IMAGE_MAP_C
#include "interface/khronos/common/khrn_int_generic_map.c"
#else
#include "interface/khronos/common/khrn_int_generic_map.h"
#endif
#undef KHRN_GENERIC_MAP_VALUE_T
#undef KHRN_GENERIC_MAP_KEY_T
#undef KHRN_GENERIC_MAP
#undef khrn_generic_map
#endif

View File

@@ -0,0 +1,467 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRONOS_MANGLE_H
#if defined KHRONOS_NAME_MANGLING || defined REMOTE_API_LOGGING || defined BCG_MULTI_THREADED
/* EGL Functions */
#define eglGetError mangled_eglGetError
#define eglGetDisplay mangled_eglGetDisplay
#define eglInitialize mangled_eglInitialize
#define eglTerminate mangled_eglTerminate
#define eglQueryString mangled_eglQueryString
#define eglGetConfigs mangled_eglGetConfigs
#define eglChooseConfig mangled_eglChooseConfig
#define eglGetConfigAttrib mangled_eglGetConfigAttrib
#define eglCreateWindowSurface mangled_eglCreateWindowSurface
#define eglCreatePbufferSurface mangled_eglCreatePbufferSurface
#define eglCreatePixmapSurface mangled_eglCreatePixmapSurface
#define eglDestroySurface mangled_eglDestroySurface
#define eglQuerySurface mangled_eglQuerySurface
#define eglBindAPI mangled_eglBindAPI
#define eglQueryAPI mangled_eglQueryAPI
#define eglWaitClient mangled_eglWaitClient
#define eglReleaseThread mangled_eglReleaseThread
#define eglCreatePbufferFromClientBuffer mangled_eglCreatePbufferFromClientBuffer
#define eglSurfaceAttrib mangled_eglSurfaceAttrib
#define eglBindTexImage mangled_eglBindTexImage
#define eglReleaseTexImage mangled_eglReleaseTexImage
#define eglSwapInterval mangled_eglSwapInterval
#define eglCreateContext mangled_eglCreateContext
#define eglDestroyContext mangled_eglDestroyContext
#define eglMakeCurrent mangled_eglMakeCurrent
#define eglGetCurrentContext mangled_eglGetCurrentContext
#define eglGetCurrentSurface mangled_eglGetCurrentSurface
#define eglGetCurrentDisplay mangled_eglGetCurrentDisplay
#define eglQueryContext mangled_eglQueryContext
#define eglWaitGL mangled_eglWaitGL
#define eglWaitNative mangled_eglWaitNative
#define eglSwapBuffers mangled_eglSwapBuffers
#define eglCopyBuffers mangled_eglCopyBuffers
#define eglGetProcAddress mangled_eglGetProcAddress
#define eglClientWaitSyncKHR mangled_eglClientWaitSyncKHR
#define eglCreateImageKHR mangled_eglCreateImageKHR
#define eglCreateSyncKHR mangled_eglCreateSyncKHR
#define eglDestroyImageKHR mangled_eglDestroyImageKHR
#define eglDestroySyncKHR mangled_eglDestroySyncKHR
#define eglGetSyncAttribKHR mangled_eglGetSyncAttribKHR
#define eglGetSyncAttribKHR mangled_eglGetSyncAttribKHR
#define eglQueryProfilingDataNOK mangled_eglQueryProfilingDataNOK
#define eglSignalSyncKHR mangled_eglSignalSyncKHR
#define eglLockSurfaceKHR mangled_eglLockSurfaceKHR
#define eglUnlockSurfaceKHR mangled_eglUnlockSurfaceKHR
#define glEGLImageTargetRenderbufferStorageOES mangled_glEGLImageTargetRenderbufferStorageOES
#define glEGLImageTargetTexture2DOES mangled_glEGLImageTargetTexture2DOES
#define eglAcquireGlobalImageBRCM mangled_eglAcquireGlobalImageBRCM
#define eglCreateCopyGlobalImageBRCM mangled_eglCreateCopyGlobalImageBRCM
#define eglCreateGlobalImageBRCM mangled_eglCreateGlobalImageBRCM
#define eglReleaseGlobalImageBRCM mangled_eglReleaseGlobalImageBRCM
#define eglInitGlobalImageBRCM mangled_eglInitGlobalImageBRCM
#define eglTermGlobalImageBRCM mangled_eglTermGlobalImageBRCM
/* OpenGL ES 1.1 and 2.0 functions */
#define glAlphaFunc mangled_glAlphaFunc
#define glClearColor mangled_glClearColor
#define glClearDepthf mangled_glClearDepthf
#define glClipPlanef mangled_glClipPlanef
#define glColor4f mangled_glColor4f
#define glDepthRangef mangled_glDepthRangef
#define glFogf mangled_glFogf
#define glFogfv mangled_glFogfv
#define glFrustumf mangled_glFrustumf
#define glGetClipPlanef mangled_glGetClipPlanef
#define glGetFloatv mangled_glGetFloatv
#define glGetLightfv mangled_glGetLightfv
#define glGetMaterialfv mangled_glGetMaterialfv
#define glGetTexEnvfv mangled_glGetTexEnvfv
#define glGetTexParameterfv mangled_glGetTexParameterfv
#define glLightModelf mangled_glLightModelf
#define glLightModelfv mangled_glLightModelfv
#define glLightf mangled_glLightf
#define glLightfv mangled_glLightfv
#define glLineWidth mangled_glLineWidth
#define glLoadMatrixf mangled_glLoadMatrixf
#define glMaterialf mangled_glMaterialf
#define glMaterialfv mangled_glMaterialfv
#define glMultMatrixf mangled_glMultMatrixf
#define glMultiTexCoord4f mangled_glMultiTexCoord4f
#define glNormal3f mangled_glNormal3f
#define glOrthof mangled_glOrthof
#define glPointParameterf mangled_glPointParameterf
#define glPointParameterfv mangled_glPointParameterfv
#define glPointSize mangled_glPointSize
#define glPolygonOffset mangled_glPolygonOffset
#define glRotatef mangled_glRotatef
#define glScalef mangled_glScalef
#define glTexEnvf mangled_glTexEnvf
#define glTexEnvfv mangled_glTexEnvfv
#define glTexParameterf mangled_glTexParameterf
#define glTexParameterfv mangled_glTexParameterfv
#define glTranslatef mangled_glTranslatef
#define glActiveTexture mangled_glActiveTexture
#define glAlphaFuncx mangled_glAlphaFuncx
#define glBindBuffer mangled_glBindBuffer
#define glBindTexture mangled_glBindTexture
#define glBlendFunc mangled_glBlendFunc
#define glBlendColor mangled_glBlendColor
#define glBufferData mangled_glBufferData
#define glBlendEquation mangled_glBlendEquation
#define glBufferSubData mangled_glBufferSubData
#define glClear mangled_glClear
#define glClearColorx mangled_glClearColorx
#define glClearDepthx mangled_glClearDepthx
#define glClearStencil mangled_glClearStencil
#define glClientActiveTexture mangled_glClientActiveTexture
#define glClipPlanex mangled_glClipPlanex
#define glColor4ub mangled_glColor4ub
#define glColor4x mangled_glColor4x
#define glColorMask mangled_glColorMask
#define glColorPointer mangled_glColorPointer
#define glCompressedTexImage2D mangled_glCompressedTexImage2D
#define glCompressedTexSubImage2D mangled_glCompressedTexSubImage2D
#define glCopyTexImage2D mangled_glCopyTexImage2D
#define glCopyTexSubImage2D mangled_glCopyTexSubImage2D
#define glCullFace mangled_glCullFace
#define glDeleteBuffers mangled_glDeleteBuffers
#define glDeleteTextures mangled_glDeleteTextures
#define glDepthFunc mangled_glDepthFunc
#define glDepthMask mangled_glDepthMask
#define glDepthRangex mangled_glDepthRangex
#define glDisable mangled_glDisable
#define glDisableClientState mangled_glDisableClientState
#define glDrawArrays mangled_glDrawArrays
#define glDrawElements mangled_glDrawElements
#define glEnable mangled_glEnable
#define glEnableClientState mangled_glEnableClientState
#define glFinish mangled_glFinish
#define glFlush mangled_glFlush
#define glFogx mangled_glFogx
#define glFogxv mangled_glFogxv
#define glFrontFace mangled_glFrontFace
#define glFrustumx mangled_glFrustumx
#define glGetBooleanv mangled_glGetBooleanv
#define glGetBufferParameteriv mangled_glGetBufferParameteriv
#define glGetClipPlanex mangled_glGetClipPlanex
#define glGenBuffers mangled_glGenBuffers
#define glGenTextures mangled_glGenTextures
#define glGetError mangled_glGetError
#define glGetFixedv mangled_glGetFixedv
#define glGetIntegerv mangled_glGetIntegerv
#define glGetLightxv mangled_glGetLightxv
#define glGetMaterialxv mangled_glGetMaterialxv
#define glGetPointerv mangled_glGetPointerv
#define glGetString mangled_glGetString
#define glGetTexEnviv mangled_glGetTexEnviv
#define glGetTexEnvxv mangled_glGetTexEnvxv
#define glGetTexParameteriv mangled_glGetTexParameteriv
#define glGetTexParameterxv mangled_glGetTexParameterxv
#define glHint mangled_glHint
#define glIsBuffer mangled_glIsBuffer
#define glIsEnabled mangled_glIsEnabled
#define glIsTexture mangled_glIsTexture
#define glLightModelx mangled_glLightModelx
#define glLightModelxv mangled_glLightModelxv
#define glLightx mangled_glLightx
#define glLightxv mangled_glLightxv
#define glLineWidthx mangled_glLineWidthx
#define glLoadIdentity mangled_glLoadIdentity
#define glLoadMatrixx mangled_glLoadMatrixx
#define glLogicOp mangled_glLogicOp
#define glMaterialx mangled_glMaterialx
#define glMaterialxv mangled_glMaterialxv
#define glMatrixMode mangled_glMatrixMode
#define glMultMatrixx mangled_glMultMatrixx
#define glMultiTexCoord4x mangled_glMultiTexCoord4x
#define glNormal3x mangled_glNormal3x
#define glNormalPointer mangled_glNormalPointer
#define glOrthox mangled_glOrthox
#define glPixelStorei mangled_glPixelStorei
#define glPointParameterx mangled_glPointParameterx
#define glPointParameterxv mangled_glPointParameterxv
#define glPointSizex mangled_glPointSizex
#define glPolygonOffsetx mangled_glPolygonOffsetx
#define glPopMatrix mangled_glPopMatrix
#define glPushMatrix mangled_glPushMatrix
#define glReadPixels mangled_glReadPixels
#define glRotatex mangled_glRotatex
#define glSampleCoverage mangled_glSampleCoverage
#define glSampleCoveragex mangled_glSampleCoveragex
#define glScalex mangled_glScalex
#define glScissor mangled_glScissor
#define glShadeModel mangled_glShadeModel
#define glStencilFunc mangled_glStencilFunc
#define glStencilMask mangled_glStencilMask
#define glStencilOp mangled_glStencilOp
#define glTexCoordPointer mangled_glTexCoordPointer
#define glTexEnvi mangled_glTexEnvi
#define glTexEnvx mangled_glTexEnvx
#define glTexEnviv mangled_glTexEnviv
#define glTexEnvxv mangled_glTexEnvxv
#define glTexImage2D mangled_glTexImage2D
#define glTexParameteri mangled_glTexParameteri
#define glTexParameterx mangled_glTexParameterx
#define glTexParameteriv mangled_glTexParameteriv
#define glTexParameterxv mangled_glTexParameterxv
#define glTexSubImage2D mangled_glTexSubImage2D
#define glTranslatex mangled_glTranslatex
#define glVertexPointer mangled_glVertexPointer
#define glViewport mangled_glViewport
#define glAttachShader mangled_glAttachShader
#define glBindAttribLocation mangled_glBindAttribLocation
#define glBlendEquationSeparate mangled_glBlendEquationSeparate
#define glBlendFuncSeparate mangled_glBlendFuncSeparate
#define glCreateProgram mangled_glCreateProgram
#define glCreateShader mangled_glCreateShader
#define glDeleteProgram mangled_glDeleteProgram
#define glDeleteShader mangled_glDeleteShader
#define glDetachShader mangled_glDetachShader
#define glDisableVertexAttribArray mangled_glDisableVertexAttribArray
#define glEnableVertexAttribArray mangled_glEnableVertexAttribArray
#define glGetActiveAttrib mangled_glGetActiveAttrib
#define glGetActiveUniform mangled_glGetActiveUniform
#define glGetAttachedShaders mangled_glGetAttachedShaders
#define glGetAttribLocation mangled_glGetAttribLocation
#define glGetProgramiv mangled_glGetProgramiv
#define glGetProgramInfoLog mangled_glGetProgramInfoLog
#define glGetUniformfv mangled_glGetUniformfv
#define glGetUniformiv mangled_glGetUniformiv
#define glGetUniformLocation mangled_glGetUniformLocation
#define glGetVertexAttribfv mangled_glGetVertexAttribfv
#define glGetVertexAttribiv mangled_glGetVertexAttribiv
#define glGetVertexAttribPointerv mangled_glGetVertexAttribPointerv
#define glIsProgram mangled_glIsProgram
#define glIsShader mangled_glIsShader
#define glLinkProgram mangled_glLinkProgram
#define glStencilFuncSeparate mangled_glStencilFuncSeparate
#define glStencilMaskSeparate mangled_glStencilMaskSeparate
#define glStencilOpSeparate mangled_glStencilOpSeparate
#define glUniform1i mangled_glUniform1i
#define glUniform2i mangled_glUniform2i
#define glUniform3i mangled_glUniform3i
#define glUniform4i mangled_glUniform4i
#define glUniform1f mangled_glUniform1f
#define glUniform2f mangled_glUniform2f
#define glUniform3f mangled_glUniform3f
#define glUniform4f mangled_glUniform4f
#define glUniform1iv mangled_glUniform1iv
#define glUniform2iv mangled_glUniform2iv
#define glUniform3iv mangled_glUniform3iv
#define glUniform4iv mangled_glUniform4iv
#define glUniform1fv mangled_glUniform1fv
#define glUniform2fv mangled_glUniform2fv
#define glUniform3fv mangled_glUniform3fv
#define glUniform4fv mangled_glUniform4fv
#define glUniformMatrix2fv mangled_glUniformMatrix2fv
#define glUniformMatrix3fv mangled_glUniformMatrix3fv
#define glUniformMatrix4fv mangled_glUniformMatrix4fv
#define glUseProgram mangled_glUseProgram
#define glValidateProgram mangled_glValidateProgram
#define glVertexAttrib1f mangled_glVertexAttrib1f
#define glVertexAttrib2f mangled_glVertexAttrib2f
#define glVertexAttrib3f mangled_glVertexAttrib3f
#define glVertexAttrib4f mangled_glVertexAttrib4f
#define glVertexAttrib1fv mangled_glVertexAttrib1fv
#define glVertexAttrib2fv mangled_glVertexAttrib2fv
#define glVertexAttrib3fv mangled_glVertexAttrib3fv
#define glVertexAttrib4fv mangled_glVertexAttrib4fv
#define glVertexAttribPointer mangled_glVertexAttribPointer
#define glCompileShader mangled_glCompileShader
#define glGetShaderiv mangled_glGetShaderiv
#define glGetShaderInfoLog mangled_glGetShaderInfoLog
#define glGetShaderSource mangled_glGetShaderSource
#define glReleaseShaderCompiler mangled_glReleaseShaderCompiler
#define glShaderSource mangled_glShaderSource
#define glShaderBinary mangled_glShaderBinary
#define glGetShaderPrecisionFormat mangled_glGetShaderPrecisionFormat
#define glIsRenderbuffer mangled_glIsRenderbuffer
#define glBindRenderbuffer mangled_glBindRenderbuffer
#define glDeleteRenderbuffers mangled_glDeleteRenderbuffers
#define glGenRenderbuffers mangled_glGenRenderbuffers
#define glRenderbufferStorage mangled_glRenderbufferStorage
#define glGetRenderbufferParameteriv mangled_glGetRenderbufferParameteriv
#define glIsFramebuffer mangled_glIsFramebuffer
#define glBindFramebuffer mangled_glBindFramebuffer
#define glDeleteFramebuffers mangled_glDeleteFramebuffers
#define glGenFramebuffers mangled_glGenFramebuffers
#define glCheckFramebufferStatus mangled_glCheckFramebufferStatus
#define glFramebufferTexture2D mangled_glFramebufferTexture2D
#define glFramebufferRenderbuffer mangled_glFramebufferRenderbuffer
#define glGetFramebufferAttachmentParameteriv mangled_glGetFramebufferAttachmentParameteriv
#define glGenerateMipmap mangled_glGenerateMipmap
#define glPointSizePointerOES mangled_glPointSizePointerOES
#define glDiscardFramebufferEXT mangled_glDiscardFramebufferEXT
#define glInsertEventMarkerEXT mangled_glInsertEventMarkerEXT
#define glPushGroupMarkerEXT mangled_glPushGroupMarkerEXT
#define glPopGroupMarkerEXT mangled_glPopGroupMarkerEXT
#define glDrawTexfOES mangled_glDrawTexfOES
#define glDrawTexfvOES mangled_glDrawTexfvOES
#define glDrawTexiOES mangled_glDrawTexiOES
#define glDrawTexivOES mangled_glDrawTexivOES
#define glDrawTexsOES mangled_glDrawTexsOES
#define glDrawTexsvOES mangled_glDrawTexsvOES
#define glDrawTexxOES mangled_glDrawTexxOES
#define glDrawTexxvOES mangled_glDrawTexxvOES
#define glIsRenderbufferOES mangled_glIsRenderbufferOES
#define glBindRenderbufferOES mangled_glBindRenderbufferOES
#define glDeleteRenderbuffersOES mangled_glDeleteRenderbuffersOES
#define glGenRenderbuffersOES mangled_glGenRenderbuffersOES
#define glRenderbufferStorageOES mangled_glRenderbufferStorageOES
#define glGetRenderbufferParameterivOES mangled_glGetRenderbufferParameterivOES
#define glIsFramebufferOES mangled_glIsFramebufferOES
#define glBindFramebufferOES mangled_glBindFramebufferOES
#define glDeleteFramebuffersOES mangled_glDeleteFramebuffersOES
#define glGenFramebuffersOES mangled_glGenFramebuffersOES
#define glCheckFramebufferStatusOES mangled_glCheckFramebufferStatusOES
#define glFramebufferRenderbufferOES mangled_glFramebufferRenderbufferOES
#define glFramebufferTexture2DOES mangled_glFramebufferTexture2DOES
#define glGetFramebufferAttachmentParameterivOES mangled_glGetFramebufferAttachmentParameterivOES
#define glGenerateMipmapOES mangled_glGenerateMipmapOES
#endif
#if defined KHRONOS_NAME_MANGLING || defined BCG_MULTI_THREADED
#define vgCreateEGLImageTargetKHR mangled_vgCreateEGLImageTargetKHR
#define vgGetError mangled_vgGetError
#define vgFlush mangled_vgFlush
#define vgFinish mangled_vgFinish
#define vgSetf mangled_vgSetf
#define vgSeti mangled_vgSeti
#define vgSetfv mangled_vgSetfv
#define vgSetiv mangled_vgSetiv
#define vgGetf mangled_vgGetf
#define vgGeti mangled_vgGeti
#define vgGetVectorSize mangled_vgGetVectorSize
#define vgGetfv mangled_vgGetfv
#define vgGetiv mangled_vgGetiv
#define vgSetParameterf mangled_vgSetParameterf
#define vgSetParameteri mangled_vgSetParameteri
#define vgSetParameterfv mangled_vgSetParameterfv
#define vgSetParameteriv mangled_vgSetParameteriv
#define vgGetParameterf mangled_vgGetParameterf
#define vgGetParameteri mangled_vgGetParameteri
#define vgGetParameterVectorSize mangled_vgGetParameterVectorSize
#define vgGetParameterfv mangled_vgGetParameterfv
#define vgGetParameteriv mangled_vgGetParameteriv
#define vgLoadIdentity mangled_vgLoadIdentity
#define vgLoadMatrix mangled_vgLoadMatrix
#define vgGetMatrix mangled_vgGetMatrix
#define vgMultMatrix mangled_vgMultMatrix
#define vgTranslate mangled_vgTranslate
#define vgScale mangled_vgScale
#define vgShear mangled_vgShear
#define vgRotate mangled_vgRotate
#define vgMask mangled_vgMask
#define vgRenderToMask mangled_vgRenderToMask
#define vgCreateMaskLayer mangled_vgCreateMaskLayer
#define vgDestroyMaskLayer mangled_vgDestroyMaskLayer
#define vgFillMaskLayer mangled_vgFillMaskLayer
#define vgCopyMask mangled_vgCopyMask
#define vgClear mangled_vgClear
#define vgCreatePath mangled_vgCreatePath
#define vgClearPath mangled_vgClearPath
#define vgDestroyPath mangled_vgDestroyPath
#define vgRemovePathCapabilities mangled_vgRemovePathCapabilities
#define vgGetPathCapabilities mangled_vgGetPathCapabilities
#define vgAppendPath mangled_vgAppendPath
#define vgAppendPathData mangled_vgAppendPathData
#define vgModifyPathCoords mangled_vgModifyPathCoords
#define vgTransformPath mangled_vgTransformPath
#define vgInterpolatePath mangled_vgInterpolatePath
#define vgPathLength mangled_vgPathLength
#define vgPointAlongPath mangled_vgPointAlongPath
#define vgPathBounds mangled_vgPathBounds
#define vgPathTransformedBounds mangled_vgPathTransformedBounds
#define vgDrawPath mangled_vgDrawPath
#define vgCreatePaint mangled_vgCreatePaint
#define vgDestroyPaint mangled_vgDestroyPaint
#define vgSetPaint mangled_vgSetPaint
#define vgGetPaint mangled_vgGetPaint
#define vgSetColor mangled_vgSetColor
#define vgGetColor mangled_vgGetColor
#define vgPaintPattern mangled_vgPaintPattern
#define vgCreateImage mangled_vgCreateImage
#define vgDestroyImage mangled_vgDestroyImage
#define vgClearImage mangled_vgClearImage
#define vgImageSubData mangled_vgImageSubData
#define vgGetImageSubData mangled_vgGetImageSubData
#define vgChildImage mangled_vgChildImage
#define vgGetParent mangled_vgGetParent
#define vgCopyImage mangled_vgCopyImage
#define vgDrawImage mangled_vgDrawImage
#define vgSetPixels mangled_vgSetPixels
#define vgWritePixels mangled_vgWritePixels
#define vgGetPixels mangled_vgGetPixels
#define vgReadPixels mangled_vgReadPixels
#define vgCopyPixels mangled_vgCopyPixels
#define vgCreateFont mangled_vgCreateFont
#define vgDestroyFont mangled_vgDestroyFont
#define vgSetGlyphToPath mangled_vgSetGlyphToPath
#define vgSetGlyphToImage mangled_vgSetGlyphToImage
#define vgClearGlyph mangled_vgClearGlyph
#define vgDrawGlyph mangled_vgDrawGlyph
#define vgDrawGlyphs mangled_vgDrawGlyphs
#define vgColorMatrix mangled_vgColorMatrix
#define vgConvolve mangled_vgConvolve
#define vgSeparableConvolve mangled_vgSeparableConvolve
#define vgGaussianBlur mangled_vgGaussianBlur
#define vgLookup mangled_vgLookup
#define vgLookupSingle mangled_vgLookupSingle
#define vgHardwareQuery mangled_vgHardwareQuery
#define vgGetString mangled_vgGetString
#define vgCreateEGLImageTargetKHR mangled_vgCreateEGLImageTargetKHR
#define vguArc mangled_vguArc
#define vguComputeWarpQuadToQuad mangled_vguComputeWarpQuadToQuad
#define vguComputeWarpQuadToSquare mangled_vguComputeWarpQuadToSquare
#define vguComputeWarpSquareToQuad mangled_vguComputeWarpSquareToQuad
#define vguEllipse mangled_vguEllipse
#define vguLine mangled_vguLine
#define vguPolygon mangled_vguPolygon
#define vguRect mangled_vguRect
#define vguRoundRect mangled_vguRoundRect
#if !defined(REMOTE_API_LOGGING) && !defined(BCG_MULTI_THREADED)
/* Internal functions */
#define egl_surface_create mangled_egl_surface_create
#define egl_surface_from_vg_image mangled_egl_surface_from_vg_image
#define egl_surface_term mangled_egl_surface_term
#define egl_surface_set_attrib mangled_egl_surface_set_attrib
#define egl_context_create mangled_egl_context_create
#define egl_context_term mangled_egl_context_term
#endif
#endif //KHRONOS_NAME_MANGLING
#endif //KHRONOS_MANGLED_H

View File

@@ -0,0 +1,331 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_PLATFORM_H
#define KHRN_CLIENT_PLATFORM_H
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_int_image.h"
#include "interface/khronos/egl/egl_int.h"
#include <stdlib.h> // for size_t
/* Per-platform types are defined in here. Most platforms can be supported
* via vcos, but 'direct' has its own header and types, which is why
* the indirection is required.
*/
#if defined(ABSTRACT_PLATFORM)
#include "interface/khronos/common/abstract/khrn_client_platform_filler_abstract.h"
#elif defined(RPC_DIRECT) && !defined(RPC_LIBRARY) && !defined(RPC_DIRECT_MULTI)
#include "interface/khronos/common/direct/khrn_client_platform_filler_direct.h"
#elif defined(KHRN_VCOS_VCHIQ)
#include "interface/khronos/common/vcos_vchiq/khrn_client_platform_filler_vcos_vchiq.h"
#else
#include "interface/khronos/common/vcos/khrn_client_platform_filler_vcos.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
named counting semaphore
*/
/* Uses forward declared ref to avoid problems with mixing direct and vcos-based
* semaphores.
*/
/*
workaround for broken platforms which don't detect threads exiting
*/
extern void platform_hint_thread_finished(void);
/*
heap
*/
/*
void *khrn_platform_malloc(size_t size, const char *desc)
Preconditions:
desc is a literal, null-terminated string
The caller of this function is contracted to later call khrn_platform_free
(or pass such responsibility on) if we don't return NULL
Postconditions:
Return value is NULL or a memory allocation of at least size bytes,
valid until khrn_platform_free is called. The memory is sufficiently
aligned that it can be used for normal data structures.
*/
extern void *khrn_platform_malloc(size_t size, const char *desc);
/*
void khrn_platform_free(void *v)
Preconditions:
v is a valid pointer returned from khrn_platform_malloc
Postconditions:
v is freed
Invariants preserved:
-
Invariants used:
-
*/
extern void khrn_platform_free(void *v);
extern void khrn_platform_maybe_free_process(void);
/*
uint64_t khronos_platform_get_process_id()
get process id
Preconditions:
-
Postconditions:
Repeated calls within a process return the same value. Calls from a different process
return a different value.
*/
extern uint64_t khronos_platform_get_process_id(void);
/*
window system
*/
#define PLATFORM_WIN_NONE ((uint32_t)0xffffffff)
#ifdef EGL_SERVER_SMALLINT
static INLINE EGLNativeWindowType platform_canonical_win(EGLNativeWindowType win)
{
switch ((uintptr_t)win) {
case (uintptr_t)NATIVE_WINDOW_800_480: return PACK_NATIVE_WINDOW(800, 480, 0, 1);
case (uintptr_t)NATIVE_WINDOW_640_480: return PACK_NATIVE_WINDOW(640, 480, 0, 1);
case (uintptr_t)NATIVE_WINDOW_320_240: return PACK_NATIVE_WINDOW(320, 240, 0, 1);
case (uintptr_t)NATIVE_WINDOW_240_320: return PACK_NATIVE_WINDOW(240, 320, 0, 1);
case (uintptr_t)NATIVE_WINDOW_64_64: return PACK_NATIVE_WINDOW(64, 64, 0, 1);
case (uintptr_t)NATIVE_WINDOW_400_480_A: return PACK_NATIVE_WINDOW(400, 480, 0, 2);
case (uintptr_t)NATIVE_WINDOW_400_480_B: return PACK_NATIVE_WINDOW(400, 480, 1, 2);
case (uintptr_t)NATIVE_WINDOW_512_512: return PACK_NATIVE_WINDOW(512, 512, 0, 1);
case (uintptr_t)NATIVE_WINDOW_360_640: return PACK_NATIVE_WINDOW(360, 640, 0, 1);
case (uintptr_t)NATIVE_WINDOW_640_360: return PACK_NATIVE_WINDOW(640, 360, 0, 1);
case (uintptr_t)NATIVE_WINDOW_1280_720: return PACK_NATIVE_WINDOW(1280, 720, 0, 1);
case (uintptr_t)NATIVE_WINDOW_1920_1080: return PACK_NATIVE_WINDOW(1920, 1080, 0, 1);
case (uintptr_t)NATIVE_WINDOW_480_320: return PACK_NATIVE_WINDOW(480, 320, 0, 1);
case (uintptr_t)NATIVE_WINDOW_1680_1050: return PACK_NATIVE_WINDOW(1680, 1050, 0, 1);
default: return win;
}
}
static INLINE uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win)
{
#ifdef ABSTRACT_PLATFORM
return (uint32_t)win;
#else
return (uint32_t)(size_t)platform_canonical_win(win);
#endif /* ABSTRACT_PLATFORM */
}
#ifndef ABSTRACT_PLATFORM
static INLINE void platform_get_dimensions(EGLDisplay dpy,
EGLNativeWindowType win, uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
{
win = platform_canonical_win(win);
*width = UNPACK_NATIVE_WINDOW_W(win);
*height = UNPACK_NATIVE_WINDOW_H(win);
#ifdef KHRN_SIMPLE_MULTISAMPLE
*width *= 2;
*height *= 2;
#endif
*swapchain_count = 0;
}
#else
void platform_get_dimensions(EGLDisplay dpy,
EGLNativeWindowType win, uint32_t *width, uint32_t *height, uint32_t *swapchain_count);
void platform_lock(void * opaque_buffer_handle);
void platform_unlock(void * opaque_buffer_handle);
#endif /* ABSTRACT_PLATFORM */
#else
/*
uint32_t platform_get_handle(EGLNativeWindowType win)
Implementation notes:
Platform-specific implementation.
Preconditions:
-
Postconditions:
If win is a valid client-side handle to window W
Then return value is a server-side handle to window W.
Else return value is PLATFORM_WIN_NONE
*/
extern uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win);
/*
void platform_get_dimensions(EGLNativeWindowType win, uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
Implementation notes:
Platform-specific implementation.
Preconditions:
win is a valid client-side window handle
width, height are valid pointers
Postconditions:
-
*/
extern void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
uint32_t *width, uint32_t *height, uint32_t *swapchain_count);
#endif
extern void platform_surface_update(uint32_t handle);
/*
bool platform_get_pixmap_info(EGLNativePixmapType pixmap, KHRN_IMAGE_WRAP_T *image);
Preconditions:
image is a valid pointer
Postconditions:
Either:
- false is returned because pixmap is an invalid pixmap handle, or
- true is returned and image is set up to describe the pixmap, and if it's a
client-side pixmap the pointer is also set
*/
extern bool platform_get_pixmap_info(EGLNativePixmapType pixmap, KHRN_IMAGE_WRAP_T *image);
/*
should look something like this:
if (regular server-side pixmap) {
handle[0] = handle;
} else if (global image server-side pixmap) {
handle[0] = id[0];
handle[1] = id[1];
}
*/
extern void platform_get_pixmap_server_handle(EGLNativePixmapType pixmap, uint32_t *handle);
extern void platform_wait_EGL(uint32_t handle);
extern void platform_retrieve_pixmap_completed(EGLNativePixmapType pixmap);
extern void platform_send_pixmap_completed(EGLNativePixmapType pixmap);
/*
bool platform_match_pixmap_api_support(EGLNativePixmapType pixmap, uint32_t api_support);
Preconditions:
pixmap is probably a valid native pixmap handle
api_support is a bitmap which is a subset of (EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT)
Postconditions:
If result is true then rendering to this pixmap using these APIs is supported on this platform
*/
extern bool platform_match_pixmap_api_support(EGLNativePixmapType pixmap, uint32_t api_support);
#if EGL_BRCM_global_image && EGL_KHR_image
extern bool platform_use_global_image_as_egl_image(uint32_t id_0, uint32_t id_1, EGLNativePixmapType pixmap, EGLint *error);
extern void platform_acquire_global_image(uint32_t id_0, uint32_t id_1);
extern void platform_release_global_image(uint32_t id_0, uint32_t id_1);
extern void platform_get_global_image_info(uint32_t id_0, uint32_t id_1,
uint32_t *pixel_format, uint32_t *width, uint32_t *height);
#endif
/* Platform optimised versions of memcpy and memcmp */
extern uint32_t platform_memcmp(const void * aLeft, const void * aRight, size_t aLen);
extern void platform_memcpy(void * aTrg, const void * aSrc, size_t aLength);
struct CLIENT_THREAD_STATE;
extern void platform_client_lock(void);
extern void platform_client_release(void);
extern void platform_init_rpc(struct CLIENT_THREAD_STATE *state);
extern void platform_term_rpc(struct CLIENT_THREAD_STATE *state);
extern void platform_maybe_free_process(void);
extern void platform_destroy_winhandle(void *a, uint32_t b);
extern uint32_t platform_get_color_format ( uint32_t format );
#if !defined(__SYMBIAN32__)
// hack for now - we want prototypes
extern void egl_gce_win_change_image(void);
#endif
#ifdef __cplusplus
}
#endif
extern EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id);
extern uint32_t khrn_platform_get_window_position(EGLNativeWindowType win);
extern void khrn_platform_release_pixmap_info(EGLNativePixmapType pixmap, KHRN_IMAGE_WRAP_T *image);
extern void khrn_platform_bind_pixmap_to_egl_image(EGLNativePixmapType pixmap, EGLImageKHR egl_image, bool send);
extern void khrn_platform_unbind_pixmap_from_egl_image(EGLImageKHR egl_image);
extern uint32_t platform_get_color_format ( uint32_t format );
extern void platform_dequeue(EGLDisplay dpy, EGLNativeWindowType window);
#include "interface/khronos/include/WF/wfc.h"
typedef struct
{
WFCDevice device;
WFCContext context;
WFCSource source;
WFCint src_x, src_y, src_width, src_height;
WFCint dest_width, dest_height;
uint32_t stop_bouncing;
uint32_t num_of_elements;
WFCElement *element;
} WFC_BOUNCE_DATA_T;
void *platform_wfc_bounce_thread(void *param);
#endif // KHRN_CLIENT_PLATFORM_H

View File

@@ -0,0 +1,37 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_platform.h"
#define KHRN_GENERIC_MAP_VALUE_NONE NULL
#define KHRN_GENERIC_MAP_VALUE_DELETED ((void *)(uintptr_t)-1)
#define KHRN_GENERIC_MAP_ALLOC khrn_platform_malloc
#define KHRN_GENERIC_MAP_FREE khrn_platform_free
#define CLIENT_POINTER_MAP_C
#include "interface/khronos/common/khrn_client_pointermap.h"

View File

@@ -0,0 +1,47 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_POINTERMAP_H
#define KHRN_CLIENT_POINTERMAP_H
#define khrn_generic_map(X) khrn_pointer_map_##X
#define KHRN_GENERIC_MAP(X) KHRN_POINTER_MAP_##X
#define KHRN_GENERIC_MAP_KEY_T uint32_t
#define KHRN_GENERIC_MAP_VALUE_T void *
#ifdef CLIENT_POINTER_MAP_C
#include "interface/khronos/common/khrn_int_generic_map.c"
#else
#include "interface/khronos/common/khrn_int_generic_map.h"
#endif
#undef KHRN_GENERIC_MAP_VALUE_T
#undef KHRN_GENERIC_MAP_KEY_T
#undef KHRN_GENERIC_MAP
#undef khrn_generic_map
#endif

View File

@@ -0,0 +1,836 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_RPC_H
#define KHRN_CLIENT_RPC_H
#define RPC_DELAYED_USE_OF_POINTERS
#include "interface/khronos/common/khrn_int_util.h"
#include "interface/khronos/common/khrn_client.h"
#include <stdlib.h> /* for size_t */
#ifdef __cplusplus
extern "C" {
#endif
# if defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
#include "rpc_platform.h"
#endif
#ifdef RPC_DIRECT
#include "middleware/khronos/egl/egl_server.h" /* for egl_server_unlock_states() */
#if !defined(V3D_LEAN) || defined(RPC_DIRECT_MULTI)
#include "middleware/khronos/common/khrn_misc.h"
#endif
#ifdef RPC_LIBRARY
#include "interface/khronos/common/khrn_client.h" /* for khrn_client_get_func_table() */
#include "applications/vmcs/khronos/khronos_server.h"
#endif
#ifdef RPC_DIRECT_MULTI
#include "interface/khronos/common/khrn_client.h" /* for khrn_client_get_func_table() */
extern int client_library_get_connection(void);
extern const KHRONOS_FUNC_TABLE_T *khronos_server_lock_func_table(int);
extern void khronos_server_unlock_func_table(void);
#endif
/******************************************************************************
type packing/unpacking macros
******************************************************************************/
#define RPC_FLOAT(f) (f)
#define RPC_ENUM(e) (e)
#define RPC_INT(i) (i)
#define RPC_INTPTR(p) (p)
#define RPC_UINT(u) (u)
#define RPC_SIZEI(s) (s)
#define RPC_SIZEIPTR(p) (p)
#define RPC_BOOLEAN(b) (b)
#define RPC_BITFIELD(b) (b)
#define RPC_FIXED(f) (f)
#define RPC_HANDLE(h) (h)
#define RPC_EGLID(i) (i)
#if defined(RPC_LIBRARY) || defined(RPC_DIRECT_MULTI)
static INLINE float RPC_FLOAT_RES(float f) { khronos_server_unlock_func_table(); return f; }
static INLINE GLenum RPC_ENUM_RES(GLenum e) { khronos_server_unlock_func_table(); return e; }
static INLINE int RPC_INT_RES(int i) { khronos_server_unlock_func_table(); return i; }
static INLINE uint32_t RPC_UINT_RES(uint32_t u) { khronos_server_unlock_func_table(); return u; }
static INLINE bool RPC_BOOLEAN_RES(bool b) { khronos_server_unlock_func_table(); return b; }
//static INLINE GLbitfield RPC_BITFIELD_RES(GLbitfield b) { khronos_server_unlock_func_table(); return b; }
static INLINE VGHandle RPC_HANDLE_RES(VGHandle h) { khronos_server_unlock_func_table(); return h; }
#else
#define RPC_FLOAT_RES(f) (f)
#define RPC_ENUM_RES(e) (e)
#define RPC_INT_RES(i) (i)
#define RPC_UINT_RES(u) (u)
#define RPC_BOOLEAN_RES(b) (b)
#define RPC_BITFIELD_RES(b) (b)
#define RPC_HANDLE_RES(h) (h)
#endif
/******************************************************************************
rpc call macros
******************************************************************************/
#ifdef RPC_DIRECT_MULTI
extern bool rpc_direct_multi_init(void);
extern void rpc_term(void);
#define RPC_INIT() rpc_direct_multi_init()
#define RPC_TERM() rpc_term()
#else
#define RPC_INIT() true
#define RPC_TERM()
#endif
#define RPC_FLUSH(thread) RPC_CALL0(khrn_misc_rpc_flush_impl, thread, no_id)
#define RPC_HIGH_PRIORITY_BEGIN(thread)
#define RPC_HIGH_PRIORITY_END(thread)
#if defined(RPC_LIBRARY) || defined(RPC_DIRECT_MULTI)
#define RPC_DO(fn, args) ((khronos_server_lock_func_table(client_library_get_connection())->fn args),khronos_server_unlock_func_table())
#define RPC_DO_RES(fn, args) (khronos_server_lock_func_table(client_library_get_connection())->fn args)
#else
#define RPC_DO(fn, args) fn args
#define RPC_DO_RES(fn, args) fn args
#endif
/*
RPC_CALL[n](fn, id, RPC_THING(p0), RPC_THING(p1), ...)
Implementation notes:
In direct mode, fn is called directly and id is ignored.
Otherwise fn is ignored and an RPC message is constructed based on id.
Preconditions:
p0, p1, etc. satisfy the precondition to fn
id matches fn
Server is up (except for a special initialise call)
Postconditions:
We promise to call fn on the server at some point in the future. The RPC calls for this
thread will occur in the same order they are made on the client.
All postconditions of fn will be satisfied (on the server)
Invariants preserved:
-
Invariants used:
-
*/
#define RPC_CALL8_MAKECURRENT(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7) RPC_CALL8(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7)
#define RPC_CALL0(fn, thread, id) RPC_DO(fn, ())
#define RPC_CALL1(fn, thread, id, p0) RPC_DO(fn, (p0))
#define RPC_CALL2(fn, thread, id, p0, p1) RPC_DO(fn, (p0, p1))
#define RPC_CALL3(fn, thread, id, p0, p1, p2) RPC_DO(fn, (p0, p1, p2))
#define RPC_CALL4(fn, thread, id, p0, p1, p2, p3) RPC_DO(fn, (p0, p1, p2, p3))
#define RPC_CALL5(fn, thread, id, p0, p1, p2, p3, p4) RPC_DO(fn, (p0, p1, p2, p3, p4))
#define RPC_CALL6(fn, thread, id, p0, p1, p2, p3, p4, p5) RPC_DO(fn, (p0, p1, p2, p3, p4, p5))
#define RPC_CALL7(fn, thread, id, p0, p1, p2, p3, p4, p5, p6) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6))
#define RPC_CALL8(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7))
#define RPC_CALL9(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8))
#define RPC_CALL10(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9))
#define RPC_CALL11(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
#define RPC_CALL16(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) \
RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15))
/*
RPC_THING_RES(RPC_CALL[n]_RES(fn, id, RPC_THING(p0), RPC_THING(p1), ...))
Implementation notes:
In direct mode, fn is called directly and id is ignored.
Otherwise fn is ignored and an RPC message is constructed based on id.
Preconditions:
p0, p1, etc. satisfy the precondition to fn
id matches fn
Server is up (except for a special initialise call)
Postconditions:
The call to fn on the server has completed
We return the return value of fn, and all postconditions of fn are satisfied (on the server)
Invariants preserved:
-
Invariants used:
-
*/
#define RPC_CALL0_RES(fn, thread, id) RPC_DO_RES(fn, ())
#define RPC_CALL1_RES(fn, thread, id, p0) RPC_DO_RES(fn, (p0))
#define RPC_CALL2_RES(fn, thread, id, p0, p1) RPC_DO_RES(fn, (p0, p1))
#define RPC_CALL3_RES(fn, thread, id, p0, p1, p2) RPC_DO_RES(fn, (p0, p1, p2))
#define RPC_CALL4_RES(fn, thread, id, p0, p1, p2, p3) RPC_DO_RES(fn, (p0, p1, p2, p3))
#define RPC_CALL5_RES(fn, thread, id, p0, p1, p2, p3, p4) RPC_DO_RES(fn, (p0, p1, p2, p3, p4))
#define RPC_CALL6_RES(fn, thread, id, p0, p1, p2, p3, p4, p5) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5))
#define RPC_CALL7_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6))
#define RPC_CALL8_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7))
#define RPC_CALL9_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8))
#define RPC_CALL10_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9))
#define RPC_CALL11_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
#define RPC_CALL12_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11))
/*
message with data in/out via control channel
*/
#define RPC_CALL1_IN_CTRL(fn, thread, id, in, len) RPC_DO(fn, (in))
#define RPC_CALL2_IN_CTRL(fn, thread, id, p0, in, len) RPC_DO(fn, (p0, in))
#define RPC_CALL3_IN_CTRL(fn, thread, id, p0, p1, in, len) RPC_DO(fn, (p0, p1, in))
#define RPC_CALL4_IN_CTRL(fn, thread, id, p0, p1, p2, in, len) RPC_DO(fn, (p0, p1, p2, in))
#define RPC_CALL5_IN_CTRL(fn, thread, id, p0, p1, p2, p3, in, len) RPC_DO(fn, (p0, p1, p2, p3, in))
#define RPC_CALL6_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, in))
#define RPC_CALL7_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, in))
#define RPC_CALL8_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, in))
#define RPC_CALL9_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, in))
#define RPC_CALL10_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, in))
/*
RPC_CALL[n]_OUT_CTRL(fn, id, RPC_THING(p0), RPC_THING(p1), ..., out)
Implementation notes:
In direct mode, fn is called directly and id is ignored.
Otherwise fn is ignored and an RPC message is constructed based on id.
The dispatch code is responsible for calculating the length of the returned data.
Preconditions:
p0, p1, ..., out satisfy the precondition to fn
id matches fn
Server is up (except for a special initialise call)
Postconditions:
The call to fn on the server has completed
We return whatever fn returned in out
Invariants preserved:
-
Invariants used:
-
*/
#define RPC_CALL1_OUT_CTRL(fn, thread, id, out) RPC_DO(fn, (out))
#define RPC_CALL2_OUT_CTRL(fn, thread, id, p0, out) RPC_DO(fn, (p0, out))
#define RPC_CALL3_OUT_CTRL(fn, thread, id, p0, p1, out) RPC_DO(fn, (p0, p1, out))
#define RPC_CALL4_OUT_CTRL(fn, thread, id, p0, p1, p2, out) RPC_DO(fn, (p0, p1, p2, out))
#define RPC_CALL5_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, out) RPC_DO(fn, (p0, p1, p2, p3, out))
#define RPC_CALL6_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, out) RPC_DO(fn, (p0, p1, p2, p3, p4, out))
#define RPC_CALL7_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, out))
#define RPC_CALL8_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, out))
#define RPC_CALL9_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, out))
#define RPC_CALL10_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, out))
#define RPC_CALL11_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, out))
#define RPC_CALL12_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, out))
#define RPC_CALL13_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out))
#define RPC_CALL14_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out))
#define RPC_CALL15_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out))
#define RPC_CALL1_OUT_CTRL_RES(fn, thread, id, out) RPC_DO_RES(fn, (out))
#define RPC_CALL2_OUT_CTRL_RES(fn, thread, id, p0, out) RPC_DO_RES(fn, (p0, out))
#define RPC_CALL3_OUT_CTRL_RES(fn, thread, id, p0, p1, out) RPC_DO_RES(fn, (p0, p1, out))
#define RPC_CALL4_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, out) RPC_DO_RES(fn, (p0, p1, p2, out))
#define RPC_CALL5_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, out) RPC_DO_RES(fn, (p0, p1, p2, p3, out))
#define RPC_CALL6_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, out))
#define RPC_CALL7_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, out))
#define RPC_CALL8_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, out))
#define RPC_CALL9_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, out))
#define RPC_CALL10_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, out))
/*
message with data in/out via bulk channel
*/
#define RPC_CALL1_IN_BULK(fn, thread, id, in, len) RPC_DO(fn, (in))
#define RPC_CALL2_IN_BULK(fn, thread, id, p0, in, len) RPC_DO(fn, (p0, in))
#define RPC_CALL3_IN_BULK(fn, thread, id, p0, p1, in, len) RPC_DO(fn, (p0, p1, in))
#define RPC_CALL4_IN_BULK(fn, thread, id, p0, p1, p2, in, len) RPC_DO(fn, (p0, p1, p2, in))
#define RPC_CALL5_IN_BULK(fn, thread, id, p0, p1, p2, p3, in, len) RPC_DO(fn, (p0, p1, p2, p3, in))
#define RPC_CALL6_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, in))
#define RPC_CALL7_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, in))
#define RPC_CALL8_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, in))
#define RPC_CALL9_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, in))
#define RPC_CALL10_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, in))
#define RPC_CALL1_OUT_BULK(fn, thread, id, out) RPC_DO(fn, (out))
#define RPC_CALL2_OUT_BULK(fn, thread, id, p0, out) RPC_DO(fn, (p0, out))
#define RPC_CALL3_OUT_BULK(fn, thread, id, p0, p1, out) RPC_DO(fn, (p0, p1, out))
#define RPC_CALL4_OUT_BULK(fn, thread, id, p0, p1, p2, out) RPC_DO(fn, (p0, p1, p2, out))
#define RPC_CALL5_OUT_BULK(fn, thread, id, p0, p1, p2, p3, out) RPC_DO(fn, (p0, p1, p2, p3, out))
#define RPC_CALL6_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, out) RPC_DO(fn, (p0, p1, p2, p3, p4, out))
#define RPC_CALL7_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, out))
#define RPC_CALL8_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, out))
#define RPC_CALL9_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, out))
#define RPC_CALL10_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) RPC_DO(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, out))
#define RPC_CALL1_IN_BULK_RES(fn, thread, id, in, len) RPC_DO_RES(fn, (in))
#define RPC_CALL2_IN_BULK_RES(fn, thread, id, p0, in, len) RPC_DO_RES(fn, (p0, in))
#define RPC_CALL3_IN_BULK_RES(fn, thread, id, p0, p1, in, len) RPC_DO_RES(fn, (p0, p1, in))
#define RPC_CALL4_IN_BULK_RES(fn, thread, id, p0, p1, p2, in, len) RPC_DO_RES(fn, (p0, p1, p2, in))
#define RPC_CALL5_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, in, len) RPC_DO_RES(fn, (p0, p1, p2, p3, in))
#define RPC_CALL6_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, in, len) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, in))
#define RPC_CALL7_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, in, len) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, in))
#define RPC_CALL8_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, in, len) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, in))
#define RPC_CALL9_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, in))
#define RPC_CALL10_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, in))
#define RPC_CALL1_OUT_BULK_RES(fn, thread, id, out) RPC_DO_RES(fn, (out))
#define RPC_CALL2_OUT_BULK_RES(fn, thread, id, p0, out) RPC_DO_RES(fn, (p0, out))
#define RPC_CALL3_OUT_BULK_RES(fn, thread, id, p0, p1, out) RPC_DO_RES(fn, (p0, p1, out))
#define RPC_CALL4_OUT_BULK_RES(fn, thread, id, p0, p1, p2, out) RPC_DO_RES(fn, (p0, p1, p2, out))
#define RPC_CALL5_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, out) RPC_DO_RES(fn, (p0, p1, p2, p3, out))
#define RPC_CALL6_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, out))
#define RPC_CALL7_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, out))
#define RPC_CALL8_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, out))
#define RPC_CALL9_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, out))
#define RPC_CALL10_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) RPC_DO_RES(fn, (p0, p1, p2, p3, p4, p5, p6, p7, p8, out))
#else /* RPC_DIRECT */
#include "interface/khronos/common/khrn_int_ids.h"
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/VG/openvg.h"
#include <string.h>
/******************************************************************************
core api
******************************************************************************/
extern bool khclient_rpc_init(void);
extern void rpc_term(void);
extern void rpc_flush(CLIENT_THREAD_STATE_T *thread);
extern void rpc_high_priority_begin(CLIENT_THREAD_STATE_T *thread);
extern void rpc_high_priority_end(CLIENT_THREAD_STATE_T *thread);
static INLINE uint32_t rpc_pad_ctrl(uint32_t len) { return (len + 0x3) & ~0x3; }
static INLINE uint32_t rpc_pad_bulk(uint32_t len) { return len; }
/* returns the length of the remainder of the merge buffer (after a flush if this length would be < len_min) */
extern uint32_t rpc_send_ctrl_longest(CLIENT_THREAD_STATE_T *thread, uint32_t len_min);
extern void rpc_send_ctrl_begin(CLIENT_THREAD_STATE_T *thread, uint32_t len); /* sum of padded lengths -- use rpc_pad_ctrl */
extern void rpc_send_ctrl_write(CLIENT_THREAD_STATE_T *thread, const uint32_t msg[], uint32_t msglen); /* len bytes read, rpc_pad_ctrl(len) bytes written */
extern void rpc_send_ctrl_end(CLIENT_THREAD_STATE_T *thread);
extern void rpc_send_bulk(CLIENT_THREAD_STATE_T *thread, const void *in, uint32_t len); /* len bytes read, rpc_pad_bulk(len) bytes written. in must remain valid until the next "releasing" rpc_end call */
extern void rpc_send_bulk_gather(CLIENT_THREAD_STATE_T *thread, const void *in, uint32_t len, int32_t stride, uint32_t n); /* n * len bytes read, rpc_pad_bulk(n * len) bytes written */
typedef enum {
RPC_RECV_FLAG_RES = 1 << 0,
RPC_RECV_FLAG_CTRL = 1 << 1,
RPC_RECV_FLAG_BULK = 1 << 2, /* len bytes written, rpc_pad_bulk(len) bytes read */
RPC_RECV_FLAG_BULK_SCATTER = 1 << 3, /* len = { len, stride, n, first_mask, last_mask }, n * len bytes written, rpc_pad_bulk(n * len) bytes read */
RPC_RECV_FLAG_LEN = 1 << 4 /* len provided by other side */
} RPC_RECV_FLAG_T;
extern uint32_t rpc_recv(CLIENT_THREAD_STATE_T *thread, void *out, uint32_t *len, RPC_RECV_FLAG_T flags);
extern void rpc_recv_bulk_gather(CLIENT_THREAD_STATE_T *thread, void *out, uint32_t *len, RPC_RECV_FLAG_T flags); /* n * len bytes read, rpc_pad_bulk(n * len) bytes written */
/*
all rpc macros and rpc_send_ctrl_begin/rpc_send_ctrl_write/rpc_send_ctrl_end
are atomic by themselves and do not require calls to rpc_begin/rpc_end
rpc_begin/rpc_end can be nested, ie the following code will not deadlock:
rpc_begin(thread);
rpc_begin(thread);
rpc_end(thread);
rpc_end(thread);
*/
extern void rpc_begin(CLIENT_THREAD_STATE_T *thread);
extern void rpc_end(CLIENT_THREAD_STATE_T *thread);
/******************************************************************************
helpers
******************************************************************************/
static INLINE void rpc_gather(void *out, const void *in, uint32_t len, int32_t stride, uint32_t n)
{
uint32_t i;
for (i = 0; i != n; ++i) {
memcpy((uint8_t *)out + (i * len), in, len);
in = (const uint8_t *)in + stride;
}
}
static INLINE void rpc_scatter(void *out, uint32_t len, int32_t stride, uint32_t n, uint32_t first_mask, uint32_t last_mask, const void *in)
{
uint32_t i;
for (i = 0; i != n; ++i) {
uint32_t first = 0, last = 0;
if (first_mask) { first = ((uint8_t *)out)[0] & first_mask; }
if (last_mask) { last = ((uint8_t *)out)[len - 1] & last_mask; }
memcpy(out, (const uint8_t *)in + (i * len), len);
if (first_mask) { ((uint8_t *)out)[0] = (uint8_t)((((uint8_t *)out)[0] & ~first_mask) | first); }
if (last_mask) { ((uint8_t *)out)[len - 1] = (uint8_t)((((uint8_t *)out)[len - 1] & ~last_mask) | last); }
out = (uint8_t *)out + stride;
}
}
/******************************************************************************
type packing/unpacking macros
******************************************************************************/
#define RPC_FLOAT(f) (float_to_bits(f))
#define RPC_ENUM(e) ((uint32_t)(e))
#define RPC_INT(i) ((uint32_t)(i))
#define RPC_INTPTR(p) ((uint32_t)(p))
#define RPC_UINT(u) ((uint32_t)(u))
#define RPC_SIZEI(s) ((uint32_t)(s))
#define RPC_SIZEIPTR(p) ((uint32_t)(p))
#define RPC_BOOLEAN(b) ((uint32_t)(b))
#define RPC_BITFIELD(b) ((uint32_t)(b))
#define RPC_FIXED(f) ((uint32_t)(f))
#define RPC_HANDLE(h) ((uint32_t)(h))
#define RPC_EGLID(i) ((uint32_t)(size_t)(i))
#define RPC_FLOAT_RES(f) (float_from_bits(f))
#define RPC_ENUM_RES(e) ((GLenum)(e))
#define RPC_INT_RES(i) ((GLint)(i))
#define RPC_UINT_RES(u) ((GLuint)(u))
#define RPC_BOOLEAN_RES(b) (!!(b))
#define RPC_BITFIELD_RES(b) ((GLbitfield)(b))
#define RPC_HANDLE_RES(h) ((VGHandle)(h))
/******************************************************************************
rpc call macros
******************************************************************************/
#define RPC_INIT() khclient_rpc_init()
#define RPC_TERM() rpc_term()
#define RPC_FLUSH(thread) rpc_flush(thread)
#define RPC_HIGH_PRIORITY_BEGIN(thread) rpc_high_priority_begin(thread)
#define RPC_HIGH_PRIORITY_END(thread) rpc_high_priority_end(thread)
#define RPC_CALL8_MAKECURRENT(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7) rpc_call8_makecurrent(thread, id, p0, p1, p2, p3, p4, p5, p6, p7)
void rpc_call8_makecurrent(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7);
uint32_t khronos_kernel_semaphore_create( uint32_t name, uint32_t count );
uint32_t khronos_kernel_semaphore_acquire( uint32_t semaphore );
uint32_t khronos_kernel_semaphore_acquire_and_release( uint32_t semaphore );
uint32_t khronos_kernel_semaphore_release( uint32_t semaphore );
uint32_t khronos_kernel_semaphore_destroy( uint32_t semaphore );
/*
helper macros (shouldn't be used directly)
*/
# if defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
#else
#ifdef __HIGHC__
/*
use XXX.../XXX syntax for variadic macros
*/
#define RPC_CALL(thread, ARGS...) \
do { \
uint32_t message_[] = { ARGS }; \
rpc_send_ctrl_begin(thread, sizeof(message_)); \
rpc_send_ctrl_write(thread, message_, sizeof(message_)); \
rpc_send_ctrl_end(thread); \
} while (0)
#define RPC_CALL_IN_CTRL(thread, IN, LEN, ARGS...) \
do { \
const void *in_ = IN; \
uint32_t len_ = LEN; \
uint32_t message_[] = { ARGS }; \
rpc_send_ctrl_begin(thread, sizeof(message_) + rpc_pad_ctrl(len_)); \
rpc_send_ctrl_write(thread, message_, sizeof(message_)); \
rpc_send_ctrl_write(thread, (uint32_t *)in_, len_); \
rpc_send_ctrl_end(thread); \
} while (0)
#define RPC_CALL_IN_BULK(thread, IN, LEN, ARGS...) \
do { \
const void *in_ = IN; \
uint32_t len_ = LEN; \
uint32_t message_[] = { ARGS, in_ ? len_ : LENGTH_SIGNAL_NULL }; \
rpc_send_ctrl_begin(thread, sizeof(message_)); \
rpc_send_ctrl_write(thread, message_, sizeof(message_)); \
rpc_send_ctrl_end(thread); \
rpc_send_bulk(thread, in_, len_); \
} while (0)
#else
/*
use c99 .../__VA_ARGS__ syntax for variadic macros
*/
#define RPC_CALL(thread, ...) \
do { \
uint32_t message_[] = { __VA_ARGS__ }; \
rpc_send_ctrl_begin(thread, sizeof(message_)); \
rpc_send_ctrl_write(thread, message_, sizeof(message_)); \
rpc_send_ctrl_end(thread); \
} while (0)
#define RPC_CALL_IN_CTRL(thread, IN, LEN, ...) \
do { \
const void *in_ = IN; \
uint32_t len_ = LEN; \
uint32_t message_[] = { __VA_ARGS__ }; \
rpc_send_ctrl_begin(thread, sizeof(message_) + rpc_pad_ctrl(len_)); \
rpc_send_ctrl_write(thread, message_, sizeof(message_)); \
rpc_send_ctrl_write(thread, in_, len_); \
rpc_send_ctrl_end(thread); \
} while (0)
#define RPC_CALL_IN_BULK(thread, IN, LEN, ...) \
do { \
const void *in_ = IN; \
uint32_t len_ = LEN; \
uint32_t message_[] = { __VA_ARGS__, in_ ? len_ : LENGTH_SIGNAL_NULL }; \
rpc_send_ctrl_begin(thread, sizeof(message_)); \
rpc_send_ctrl_write(thread, message_, sizeof(message_)); \
rpc_send_ctrl_end(thread); \
rpc_send_bulk(thread, in_, len_); \
} while (0)
#endif
#endif
/*
just message
*/
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE void rpc_call0(CLIENT_THREAD_STATE_T *thread, uint32_t id) { RPC_CALL(thread, id); }
static INLINE void rpc_call1(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0) { RPC_CALL(thread, id, p0); }
static INLINE void rpc_call2(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1) { RPC_CALL(thread, id, p0, p1); }
static INLINE void rpc_call3(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2) { RPC_CALL(thread, id, p0, p1, p2); }
static INLINE void rpc_call4(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) { RPC_CALL(thread, id, p0, p1, p2, p3); }
static INLINE void rpc_call5(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) { RPC_CALL(thread, id, p0, p1, p2, p3, p4); }
static INLINE void rpc_call6(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5) { RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5); }
static INLINE void rpc_call7(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6) { RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6); }
static INLINE void rpc_call8(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7) { RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7); }
static INLINE void rpc_call9(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8) { RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); }
static INLINE void rpc_call10(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9) { RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
static INLINE void rpc_call16(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7,
uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, uint32_t p13, uint32_t p14, uint32_t p15)
{ RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); }
static INLINE void rpc_call18(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7,
uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, uint32_t p13, uint32_t p14, uint32_t p15, uint32_t p16, uint32_t p17)
{ RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17); }
#endif
#define RPC_CALL0(fn, thread, id) rpc_call0(thread, id)
#define RPC_CALL1(fn, thread, id, p0) rpc_call1(thread, id, p0)
#define RPC_CALL2(fn, thread, id, p0, p1) rpc_call2(thread, id, p0, p1)
#define RPC_CALL3(fn, thread, id, p0, p1, p2) rpc_call3(thread, id, p0, p1, p2)
#define RPC_CALL4(fn, thread, id, p0, p1, p2, p3) rpc_call4(thread, id, p0, p1, p2, p3)
#define RPC_CALL5(fn, thread, id, p0, p1, p2, p3, p4) rpc_call5(thread, id, p0, p1, p2, p3, p4)
#define RPC_CALL6(fn, thread, id, p0, p1, p2, p3, p4, p5) rpc_call6(thread, id, p0, p1, p2, p3, p4, p5)
#define RPC_CALL7(fn, thread, id, p0, p1, p2, p3, p4, p5, p6) rpc_call7(thread, id, p0, p1, p2, p3, p4, p5, p6)
#define RPC_CALL8(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7) rpc_call8(thread, id, p0, p1, p2, p3, p4, p5, p6, p7)
#define RPC_CALL9(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8) rpc_call9(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8)
#define RPC_CALL10(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) rpc_call10(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)
#define RPC_CALL11(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) rpc_call10(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
#define RPC_CALL16(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) \
rpc_call16(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)
#define RPC_CALL18(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17) \
rpc_call18(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17)
/*
RPC_THING_RES(rpc_call[n]_res(id, RPC_THING(p0), RPC_THING(p1), ...))
Implementation notes:
-
Preconditions:
Not in RPC_DIRECT mode
p0, p1, etc. satisfy the preconditions of the operation identified by id
Server is up (except for a special initialise call)
Postconditions:
The operation identified by id has completed on the server
We return the result of this operation, and all postconditions are satisfied (on the server)
Invariants preserved:
-
Invariants used:
-
*/
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE uint32_t rpc_call0_res(CLIENT_THREAD_STATE_T *thread, uint32_t id) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call1_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call2_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call3_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call4_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call5_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call6_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call7_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call8_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call9_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call10_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call11_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call12_res(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
#endif
#define RPC_CALL0_RES(fn, thread, id) rpc_call0_res(thread, id)
#define RPC_CALL1_RES(fn, thread, id, p0) rpc_call1_res(thread, id, p0)
#define RPC_CALL2_RES(fn, thread, id, p0, p1) rpc_call2_res(thread, id, p0, p1)
#define RPC_CALL3_RES(fn, thread, id, p0, p1, p2) rpc_call3_res(thread, id, p0, p1, p2)
#define RPC_CALL4_RES(fn, thread, id, p0, p1, p2, p3) rpc_call4_res(thread, id, p0, p1, p2, p3)
#define RPC_CALL5_RES(fn, thread, id, p0, p1, p2, p3, p4) rpc_call5_res(thread, id, p0, p1, p2, p3, p4)
#define RPC_CALL6_RES(fn, thread, id, p0, p1, p2, p3, p4, p5) rpc_call6_res(thread, id, p0, p1, p2, p3, p4, p5)
#define RPC_CALL7_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6) rpc_call7_res(thread, id, p0, p1, p2, p3, p4, p5, p6)
#define RPC_CALL8_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7) rpc_call8_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7)
#define RPC_CALL9_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8) rpc_call9_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8)
#define RPC_CALL10_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) rpc_call10_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)
#define RPC_CALL11_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) rpc_call11_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
#define RPC_CALL12_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) rpc_call12_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
/*
message with data in/out via control channel
*/
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE void rpc_call1_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id); }
static INLINE void rpc_call2_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0); }
static INLINE void rpc_call3_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1); }
static INLINE void rpc_call4_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1, p2); }
static INLINE void rpc_call5_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1, p2, p3); }
static INLINE void rpc_call6_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1, p2, p3, p4); }
static INLINE void rpc_call7_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1, p2, p3, p4, p5); }
static INLINE void rpc_call8_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6); }
static INLINE void rpc_call9_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6, p7); }
static INLINE void rpc_call10_in_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, const void *in, uint32_t len) { RPC_CALL_IN_CTRL(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); }
#endif
#define RPC_CALL1_IN_CTRL(fn, thread, id, in, len) rpc_call1_in_ctrl(thread, id, in, len)
#define RPC_CALL2_IN_CTRL(fn, thread, id, p0, in, len) rpc_call2_in_ctrl(thread, id, p0, in, len)
#define RPC_CALL3_IN_CTRL(fn, thread, id, p0, p1, in, len) rpc_call3_in_ctrl(thread, id, p0, p1, in, len)
#define RPC_CALL4_IN_CTRL(fn, thread, id, p0, p1, p2, in, len) rpc_call4_in_ctrl(thread, id, p0, p1, p2, in, len)
#define RPC_CALL5_IN_CTRL(fn, thread, id, p0, p1, p2, p3, in, len) rpc_call5_in_ctrl(thread, id, p0, p1, p2, p3, in, len)
#define RPC_CALL6_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, in, len) rpc_call6_in_ctrl(thread, id, p0, p1, p2, p3, p4, in, len)
#define RPC_CALL7_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, in, len) rpc_call7_in_ctrl(thread, id, p0, p1, p2, p3, p4, p5, in, len)
#define RPC_CALL8_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, in, len) rpc_call8_in_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, in, len)
#define RPC_CALL9_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len) rpc_call9_in_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len)
#define RPC_CALL10_IN_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len) rpc_call10_in_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len)
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE void rpc_call1_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, void *out) { rpc_begin(thread); RPC_CALL(thread, id); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call2_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call3_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call4_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call5_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call6_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call7_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call8_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call9_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call10_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call11_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call12_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call13_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call14_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call15_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, uint32_t p13, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
#endif
#define RPC_CALL1_OUT_CTRL(fn, thread, id, out) rpc_call1_out_ctrl(thread, id, out)
#define RPC_CALL2_OUT_CTRL(fn, thread, id, p0, out) rpc_call2_out_ctrl(thread, id, p0, out)
#define RPC_CALL3_OUT_CTRL(fn, thread, id, p0, p1, out) rpc_call3_out_ctrl(thread, id, p0, p1, out)
#define RPC_CALL4_OUT_CTRL(fn, thread, id, p0, p1, p2, out) rpc_call4_out_ctrl(thread, id, p0, p1, p2, out)
#define RPC_CALL5_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, out) rpc_call5_out_ctrl(thread, id, p0, p1, p2, p3, out)
#define RPC_CALL6_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, out) rpc_call6_out_ctrl(thread, id, p0, p1, p2, p3, p4, out)
#define RPC_CALL7_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, out) rpc_call7_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, out)
#define RPC_CALL8_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) rpc_call8_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, out)
#define RPC_CALL9_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) rpc_call9_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out)
#define RPC_CALL10_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) rpc_call10_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out)
#define RPC_CALL11_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, out) rpc_call11_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, out)
#define RPC_CALL12_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, out) rpc_call12_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, out)
#define RPC_CALL13_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out) rpc_call13_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out)
#define RPC_CALL14_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out) rpc_call14_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out)
#define RPC_CALL15_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out) rpc_call15_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out)
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE uint32_t rpc_call1_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call2_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call3_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call4_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call5_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call6_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call7_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call8_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call9_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call10_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
#endif
#define RPC_CALL1_OUT_CTRL_RES(fn, thread, id, out) rpc_call1_out_ctrl_res(thread, id, out)
#define RPC_CALL2_OUT_CTRL_RES(fn, thread, id, p0, out) rpc_call2_out_ctrl_res(thread, id, p0, out)
#define RPC_CALL3_OUT_CTRL_RES(fn, thread, id, p0, p1, out) rpc_call3_out_ctrl_res(thread, id, p0, p1, out)
#define RPC_CALL4_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, out) rpc_call4_out_ctrl_res(thread, id, p0, p1, p2, out)
#define RPC_CALL5_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, out) rpc_call5_out_ctrl_res(thread, id, p0, p1, p2, p3, out)
#define RPC_CALL6_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, out) rpc_call6_out_ctrl_res(thread, id, p0, p1, p2, p3, p4, out)
#define RPC_CALL7_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, out) rpc_call7_out_ctrl_res(thread, id, p0, p1, p2, p3, p4, p5, out)
#define RPC_CALL8_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) rpc_call8_out_ctrl_res(thread, id, p0, p1, p2, p3, p4, p5, p6, out)
#define RPC_CALL9_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) rpc_call9_out_ctrl_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out)
#define RPC_CALL10_OUT_CTRL_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) rpc_call10_out_ctrl_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out)
/*
message with data in/out via bulk channel
if in is NULL, no bulk transfer will be performed and LENGTH_SIGNAL_NULL will
be passed instead of len
*/
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE void rpc_call1_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id); rpc_end(thread); }
static INLINE void rpc_call2_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0); rpc_end(thread); }
static INLINE void rpc_call3_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1); rpc_end(thread); }
static INLINE void rpc_call4_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2); rpc_end(thread); }
static INLINE void rpc_call5_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3); rpc_end(thread); }
static INLINE void rpc_call6_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4); rpc_end(thread); }
static INLINE void rpc_call7_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5); rpc_end(thread); }
static INLINE void rpc_call8_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6); rpc_end(thread); }
static INLINE void rpc_call9_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6, p7); rpc_end(thread); }
static INLINE void rpc_call10_in_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, const void *in, uint32_t len) { rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); rpc_end(thread); }
#endif
#define RPC_CALL1_IN_BULK(fn, thread, id, in, len) rpc_call1_in_bulk(thread, id, in, len)
#define RPC_CALL2_IN_BULK(fn, thread, id, p0, in, len) rpc_call2_in_bulk(thread, id, p0, in, len)
#define RPC_CALL3_IN_BULK(fn, thread, id, p0, p1, in, len) rpc_call3_in_bulk(thread, id, p0, p1, in, len)
#define RPC_CALL4_IN_BULK(fn, thread, id, p0, p1, p2, in, len) rpc_call4_in_bulk(thread, id, p0, p1, p2, in, len)
#define RPC_CALL5_IN_BULK(fn, thread, id, p0, p1, p2, p3, in, len) rpc_call5_in_bulk(thread, id, p0, p1, p2, p3, in, len)
#define RPC_CALL6_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, in, len) rpc_call6_in_bulk(thread, id, p0, p1, p2, p3, p4, in, len)
#define RPC_CALL7_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, in, len) rpc_call7_in_bulk(thread, id, p0, p1, p2, p3, p4, p5, in, len)
#define RPC_CALL8_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, in, len) rpc_call8_in_bulk(thread, id, p0, p1, p2, p3, p4, p5, p6, in, len)
#define RPC_CALL9_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len) rpc_call9_in_bulk(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len)
#define RPC_CALL10_IN_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len) rpc_call10_in_bulk(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len)
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE void rpc_call1_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, void *out) { rpc_begin(thread); RPC_CALL(thread, id); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call2_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call3_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call4_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call5_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call6_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call7_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call8_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call9_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
static INLINE void rpc_call10_out_bulk(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
#endif
#define RPC_CALL1_OUT_BULK(fn, thread, id, out) rpc_call1_out_bulk(thread, id, out)
#define RPC_CALL2_OUT_BULK(fn, thread, id, p0, out) rpc_call2_out_bulk(thread, id, p0, out)
#define RPC_CALL3_OUT_BULK(fn, thread, id, p0, p1, out) rpc_call3_out_bulk(thread, id, p0, p1, out)
#define RPC_CALL4_OUT_BULK(fn, thread, id, p0, p1, p2, out) rpc_call4_out_bulk(thread, id, p0, p1, p2, out)
#define RPC_CALL5_OUT_BULK(fn, thread, id, p0, p1, p2, p3, out) rpc_call5_out_bulk(thread, id, p0, p1, p2, p3, out)
#define RPC_CALL6_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, out) rpc_call6_out_bulk(thread, id, p0, p1, p2, p3, p4, out)
#define RPC_CALL7_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, out) rpc_call7_out_bulk(thread, id, p0, p1, p2, p3, p4, p5, out)
#define RPC_CALL8_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) rpc_call8_out_bulk(thread, id, p0, p1, p2, p3, p4, p5, p6, out)
#define RPC_CALL9_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) rpc_call9_out_bulk(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out)
#define RPC_CALL10_OUT_BULK(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) rpc_call10_out_bulk(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out)
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE uint32_t rpc_call1_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call2_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call3_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call4_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call5_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call6_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call7_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call8_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call9_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6, p7); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call10_in_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, const void *in, uint32_t len) { uint32_t res; rpc_begin(thread); RPC_CALL_IN_BULK(thread, in, len, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); res = rpc_recv(thread, NULL, NULL, RPC_RECV_FLAG_RES); rpc_end(thread); return res; }
#endif
#define RPC_CALL1_IN_BULK_RES(fn, thread, id, in, len) rpc_call1_in_bulk_res(thread, id, in, len)
#define RPC_CALL2_IN_BULK_RES(fn, thread, id, p0, in, len) rpc_call2_in_bulk_res(thread, id, p0, in, len)
#define RPC_CALL3_IN_BULK_RES(fn, thread, id, p0, p1, in, len) rpc_call3_in_bulk_res(thread, id, p0, p1, in, len)
#define RPC_CALL4_IN_BULK_RES(fn, thread, id, p0, p1, p2, in, len) rpc_call4_in_bulk_res(thread, id, p0, p1, p2, in, len)
#define RPC_CALL5_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, in, len) rpc_call5_in_bulk_res(thread, id, p0, p1, p2, p3, in, len)
#define RPC_CALL6_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, in, len) rpc_call6_in_bulk_res(thread, id, p0, p1, p2, p3, p4, in, len)
#define RPC_CALL7_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, in, len) rpc_call7_in_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, in, len)
#define RPC_CALL8_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, in, len) rpc_call8_in_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, p6, in, len)
#define RPC_CALL9_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len) rpc_call9_in_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, in, len)
#define RPC_CALL10_IN_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len) rpc_call10_in_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, in, len)
# if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
static INLINE uint32_t rpc_call1_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call2_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call3_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call4_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call5_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call6_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call7_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call8_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call9_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
static INLINE uint32_t rpc_call10_out_bulk_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
#endif
#define RPC_CALL1_OUT_BULK_RES(fn, thread, id, out) rpc_call1_out_bulk_res(thread, id, out)
#define RPC_CALL2_OUT_BULK_RES(fn, thread, id, p0, out) rpc_call2_out_bulk_res(thread, id, p0, out)
#define RPC_CALL3_OUT_BULK_RES(fn, thread, id, p0, p1, out) rpc_call3_out_bulk_res(thread, id, p0, p1, out)
#define RPC_CALL4_OUT_BULK_RES(fn, thread, id, p0, p1, p2, out) rpc_call4_out_bulk_res(thread, id, p0, p1, p2, out)
#define RPC_CALL5_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, out) rpc_call5_out_bulk_res(thread, id, p0, p1, p2, p3, out)
#define RPC_CALL6_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, out) rpc_call6_out_bulk_res(thread, id, p0, p1, p2, p3, p4, out)
#define RPC_CALL7_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, out) rpc_call7_out_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, out)
#define RPC_CALL8_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, out) rpc_call8_out_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, p6, out)
#define RPC_CALL9_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out) rpc_call9_out_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, out)
#define RPC_CALL10_OUT_BULK_RES(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out) rpc_call10_out_bulk_res(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, out)
#endif /* RPC_DIRECT */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,467 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRONOS_MANGLE_H
#if defined KHRONOS_NAME_MANGLING || defined REMOTE_API_LOGGING || defined BCG_MULTI_THREADED
/* EGL Functions */
#undef eglGetError
#undef eglGetDisplay
#undef eglInitialize
#undef eglTerminate
#undef eglQueryString
#undef eglGetConfigs
#undef eglChooseConfig
#undef eglGetConfigAttrib
#undef eglCreateWindowSurface
#undef eglCreatePbufferSurface
#undef eglCreatePixmapSurface
#undef eglDestroySurface
#undef eglQuerySurface
#undef eglBindAPI
#undef eglQueryAPI
#undef eglWaitClient
#undef eglReleaseThread
#undef eglCreatePbufferFromClientBuffer
#undef eglSurfaceAttrib
#undef eglBindTexImage
#undef eglReleaseTexImage
#undef eglSwapInterval
#undef eglCreateContext
#undef eglDestroyContext
#undef eglMakeCurrent
#undef eglGetCurrentContext
#undef eglGetCurrentSurface
#undef eglGetCurrentDisplay
#undef eglQueryContext
#undef eglWaitGL
#undef eglWaitNative
#undef eglSwapBuffers
#undef eglCopyBuffers
#undef eglGetProcAddress
#undef eglClientWaitSyncKHR
#undef eglCreateImageKHR
#undef eglCreateSyncKHR
#undef eglDestroyImageKHR
#undef eglDestroySyncKHR
#undef eglGetSyncAttribKHR
#undef eglGetSyncAttribKHR
#undef eglQueryProfilingDataNOK
#undef eglSignalSyncKHR
#undef eglLockSurfaceKHR
#undef eglUnlockSurfaceKHR
#undef glEGLImageTargetRenderbufferStorageOES
#undef glEGLImageTargetTexture2DOES
#undef eglAcquireGlobalImageBRCM
#undef eglCreateCopyGlobalImageBRCM
#undef eglCreateGlobalImageBRCM
#undef eglReleaseGlobalImageBRCM
#undef eglInitGlobalImageBRCM
#undef eglTermGlobalImageBRCM
/* OpenGL ES 1.1 and 2.0 functions */
#undef glAlphaFunc
#undef glClearColor
#undef glClearDepthf
#undef glClipPlanef
#undef glColor4f
#undef glDepthRangef
#undef glFogf
#undef glFogfv
#undef glFrustumf
#undef glGetClipPlanef
#undef glGetFloatv
#undef glGetLightfv
#undef glGetMaterialfv
#undef glGetTexEnvfv
#undef glGetTexParameterfv
#undef glLightModelf
#undef glLightModelfv
#undef glLightf
#undef glLightfv
#undef glLineWidth
#undef glLoadMatrixf
#undef glMaterialf
#undef glMaterialfv
#undef glMultMatrixf
#undef glMultiTexCoord4f
#undef glNormal3f
#undef glOrthof
#undef glPointParameterf
#undef glPointParameterfv
#undef glPointSize
#undef glPolygonOffset
#undef glRotatef
#undef glScalef
#undef glTexEnvf
#undef glTexEnvfv
#undef glTexParameterf
#undef glTexParameterfv
#undef glTranslatef
#undef glActiveTexture
#undef glAlphaFuncx
#undef glBindBuffer
#undef glBindTexture
#undef glBlendFunc
#undef glBlendColor
#undef glBufferData
#undef glBlendEquation
#undef glBufferSubData
#undef glClear
#undef glClearColorx
#undef glClearDepthx
#undef glClearStencil
#undef glClientActiveTexture
#undef glClipPlanex
#undef glColor4ub
#undef glColor4x
#undef glColorMask
#undef glColorPointer
#undef glCompressedTexImage2D
#undef glCompressedTexSubImage2D
#undef glCopyTexImage2D
#undef glCopyTexSubImage2D
#undef glCullFace
#undef glDeleteBuffers
#undef glDeleteTextures
#undef glDepthFunc
#undef glDepthMask
#undef glDepthRangex
#undef glDisable
#undef glDisableClientState
#undef glDrawArrays
#undef glDrawElements
#undef glEnable
#undef glEnableClientState
#undef glFinish
#undef glFlush
#undef glFogx
#undef glFogxv
#undef glFrontFace
#undef glFrustumx
#undef glGetBooleanv
#undef glGetBufferParameteriv
#undef glGetClipPlanex
#undef glGenBuffers
#undef glGenTextures
#undef glGetError
#undef glGetFixedv
#undef glGetIntegerv
#undef glGetLightxv
#undef glGetMaterialxv
#undef glGetPointerv
#undef glGetString
#undef glGetTexEnviv
#undef glGetTexEnvxv
#undef glGetTexParameteriv
#undef glGetTexParameterxv
#undef glHint
#undef glIsBuffer
#undef glIsEnabled
#undef glIsTexture
#undef glLightModelx
#undef glLightModelxv
#undef glLightx
#undef glLightxv
#undef glLineWidthx
#undef glLoadIdentity
#undef glLoadMatrixx
#undef glLogicOp
#undef glMaterialx
#undef glMaterialxv
#undef glMatrixMode
#undef glMultMatrixx
#undef glMultiTexCoord4x
#undef glNormal3x
#undef glNormalPointer
#undef glOrthox
#undef glPixelStorei
#undef glPointParameterx
#undef glPointParameterxv
#undef glPointSizex
#undef glPolygonOffsetx
#undef glPopMatrix
#undef glPushMatrix
#undef glReadPixels
#undef glRotatex
#undef glSampleCoverage
#undef glSampleCoveragex
#undef glScalex
#undef glScissor
#undef glShadeModel
#undef glStencilFunc
#undef glStencilMask
#undef glStencilOp
#undef glTexCoordPointer
#undef glTexEnvi
#undef glTexEnvx
#undef glTexEnviv
#undef glTexEnvxv
#undef glTexImage2D
#undef glTexParameteri
#undef glTexParameterx
#undef glTexParameteriv
#undef glTexParameterxv
#undef glTexSubImage2D
#undef glTranslatex
#undef glVertexPointer
#undef glViewport
#undef glAttachShader
#undef glBindAttribLocation
#undef glBlendEquationSeparate
#undef glBlendFuncSeparate
#undef glCreateProgram
#undef glCreateShader
#undef glDeleteProgram
#undef glDeleteShader
#undef glDetachShader
#undef glDisableVertexAttribArray
#undef glEnableVertexAttribArray
#undef glGetActiveAttrib
#undef glGetActiveUniform
#undef glGetAttachedShaders
#undef glGetAttribLocation
#undef glGetProgramiv
#undef glGetProgramInfoLog
#undef glGetUniformfv
#undef glGetUniformiv
#undef glGetUniformLocation
#undef glGetVertexAttribfv
#undef glGetVertexAttribiv
#undef glGetVertexAttribPointerv
#undef glIsProgram
#undef glIsShader
#undef glLinkProgram
#undef glStencilFuncSeparate
#undef glStencilMaskSeparate
#undef glStencilOpSeparate
#undef glUniform1i
#undef glUniform2i
#undef glUniform3i
#undef glUniform4i
#undef glUniform1f
#undef glUniform2f
#undef glUniform3f
#undef glUniform4f
#undef glUniform1iv
#undef glUniform2iv
#undef glUniform3iv
#undef glUniform4iv
#undef glUniform1fv
#undef glUniform2fv
#undef glUniform3fv
#undef glUniform4fv
#undef glUniformMatrix2fv
#undef glUniformMatrix3fv
#undef glUniformMatrix4fv
#undef glUseProgram
#undef glValidateProgram
#undef glVertexAttrib1f
#undef glVertexAttrib2f
#undef glVertexAttrib3f
#undef glVertexAttrib4f
#undef glVertexAttrib1fv
#undef glVertexAttrib2fv
#undef glVertexAttrib3fv
#undef glVertexAttrib4fv
#undef glVertexAttribPointer
#undef glCompileShader
#undef glGetShaderiv
#undef glGetShaderInfoLog
#undef glGetShaderSource
#undef glReleaseShaderCompiler
#undef glShaderSource
#undef glShaderBinary
#undef glGetShaderPrecisionFormat
#undef glIsRenderbuffer
#undef glBindRenderbuffer
#undef glDeleteRenderbuffers
#undef glGenRenderbuffers
#undef glRenderbufferStorage
#undef glGetRenderbufferParameteriv
#undef glIsFramebuffer
#undef glBindFramebuffer
#undef glDeleteFramebuffers
#undef glGenFramebuffers
#undef glCheckFramebufferStatus
#undef glFramebufferTexture2D
#undef glFramebufferRenderbuffer
#undef glGetFramebufferAttachmentParameteriv
#undef glGenerateMipmap
#undef glPointSizePointerOES
#undef glDiscardFramebufferEXT
#undef glInsertEventMarkerEXT
#undef glPushGroupMarkerEXT
#undef glPopGroupMarkerEXT
#undef glDrawTexfOES
#undef glDrawTexfvOES
#undef glDrawTexiOES
#undef glDrawTexivOES
#undef glDrawTexsOES
#undef glDrawTexsvOES
#undef glDrawTexxOES
#undef glDrawTexxvOES
#undef glIsRenderbufferOES
#undef glBindRenderbufferOES
#undef glDeleteRenderbuffersOES
#undef glGenRenderbuffersOES
#undef glRenderbufferStorageOES
#undef glGetRenderbufferParameterivOES
#undef glIsFramebufferOES
#undef glBindFramebufferOES
#undef glDeleteFramebuffersOES
#undef glGenFramebuffersOES
#undef glCheckFramebufferStatusOES
#undef glFramebufferRenderbufferOES
#undef glFramebufferTexture2DOES
#undef glGetFramebufferAttachmentParameterivOES
#undef glGenerateMipmapOES
/* Internal functions */
#undef egl_surface_create
#undef egl_surface_from_vg_image
#undef egl_surface_term
#undef egl_surface_set_attrib
#undef egl_context_create
#undef egl_context_term
#endif
#if defined KHRONOS_NAME_MANGLING || defined BCG_MULTI_THREADED
/* OpenVG functions */
#undef vgCreateEGLImageTargetKHR
#undef vgGetError
#undef vgFlush
#undef vgFinish
#undef vgSetf
#undef vgSeti
#undef vgSetfv
#undef vgSetiv
#undef vgGetf
#undef vgGeti
#undef vgGetVectorSize
#undef vgGetfv
#undef vgGetiv
#undef vgSetParameterf
#undef vgSetParameteri
#undef vgSetParameterfv
#undef vgSetParameteriv
#undef vgGetParameterf
#undef vgGetParameteri
#undef vgGetParameterVectorSize
#undef vgGetParameterfv
#undef vgGetParameteriv
#undef vgLoadIdentity
#undef vgLoadMatrix
#undef vgGetMatrix
#undef vgMultMatrix
#undef vgTranslate
#undef vgScale
#undef vgShear
#undef vgRotate
#undef vgMask
#undef vgRenderToMask
#undef vgCreateMaskLayer
#undef vgDestroyMaskLayer
#undef vgFillMaskLayer
#undef vgCopyMask
#undef vgClear
#undef vgCreatePath
#undef vgClearPath
#undef vgDestroyPath
#undef vgRemovePathCapabilities
#undef vgGetPathCapabilities
#undef vgAppendPath
#undef vgAppendPathData
#undef vgModifyPathCoords
#undef vgTransformPath
#undef vgInterpolatePath
#undef vgPathLength
#undef vgPointAlongPath
#undef vgPathBounds
#undef vgPathTransformedBounds
#undef vgDrawPath
#undef vgCreatePaint
#undef vgDestroyPaint
#undef vgSetPaint
#undef vgGetPaint
#undef vgSetColor
#undef vgGetColor
#undef vgPaintPattern
#undef vgCreateImage
#undef vgDestroyImage
#undef vgClearImage
#undef vgImageSubData
#undef vgGetImageSubData
#undef vgChildImage
#undef vgGetParent
#undef vgCopyImage
#undef vgDrawImage
#undef vgSetPixels
#undef vgWritePixels
#undef vgGetPixels
#undef vgReadPixels
#undef vgCopyPixels
#undef vgCreateFont
#undef vgDestroyFont
#undef vgSetGlyphToPath
#undef vgSetGlyphToImage
#undef vgClearGlyph
#undef vgDrawGlyph
#undef vgDrawGlyphs
#undef vgColorMatrix
#undef vgConvolve
#undef vgSeparableConvolve
#undef vgGaussianBlur
#undef vgLookup
#undef vgLookupSingle
#undef vgHardwareQuery
#undef vgGetString
#undef vgCreateEGLImageTargetKHR
#undef vguArc
#undef vguComputeWarpQuadToQuad
#undef vguComputeWarpQuadToSquare
#undef vguComputeWarpSquareToQuad
#undef vguEllipse
#undef vguLine
#undef vguPolygon
#undef vguRect
#undef vguRoundRect
#endif //KHRONOS_NAME_MANGLING
#endif //KHRONOS_MANGLED_H

View File

@@ -0,0 +1,82 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/common/khrn_client_vector.h"
#include <stdlib.h>
#include <string.h>
void khrn_vector_init(KHRN_VECTOR_T *vector, uint32_t capacity)
{
vector->data = (capacity == 0) ? NULL : khrn_platform_malloc(capacity, "KHRN_VECTOR_T.data");
vector->capacity = vector->data ? capacity : 0;
vector->size = 0;
}
void khrn_vector_term(KHRN_VECTOR_T *vector)
{
if (vector->data) {
khrn_platform_free(vector->data);
}
}
bool khrn_vector_extend(KHRN_VECTOR_T *vector, uint32_t size)
{
uint32_t req_capacity = vector->size + size;
if (req_capacity > vector->capacity) {
uint32_t new_capacity = _max(vector->capacity + (vector->capacity >> 1), req_capacity);
void *new_data = khrn_platform_malloc(new_capacity, "KHRN_VECTOR_T.data");
if (!new_data) {
new_capacity = req_capacity;
new_data = khrn_platform_malloc(new_capacity, "KHRN_VECTOR_T.data");
if (!new_data) {
return false;
}
}
if (vector->data) {
memcpy(new_data, vector->data, vector->size);
khrn_platform_free(vector->data);
}
vector->data = new_data;
vector->capacity = new_capacity;
}
vector->size += size;
return true;
}
void khrn_vector_clear(KHRN_VECTOR_T *vector)
{
if (vector->data) {
khrn_platform_free(vector->data);
}
vector->data = NULL;
vector->capacity = 0;
vector->size = 0;
}

View File

@@ -0,0 +1,43 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_VECTOR_H
#define KHRN_CLIENT_VECTOR_H
typedef struct {
void *data;
uint32_t capacity;
uint32_t size;
} KHRN_VECTOR_T;
extern void khrn_vector_init(KHRN_VECTOR_T *vector, uint32_t capacity);
extern void khrn_vector_term(KHRN_VECTOR_T *vector);
extern bool khrn_vector_extend(KHRN_VECTOR_T *vector, uint32_t size);
extern void khrn_vector_clear(KHRN_VECTOR_T *vector);
#endif

View File

@@ -0,0 +1,89 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_INT_COLOR_H
#define KHRN_INT_COLOR_H
#include "interface/khronos/common/khrn_int_util.h"
extern const uint8_t COLOR_S_TO_LIN[256];
extern const uint16_t COLOR_S_TO_LIN16[256];
extern const uint8_t COLOR_LIN_TO_S[256];
extern const uint8_t COLOR_LIN16_TO_S[320];
extern const uint32_t COLOR_RECIP[256];
static INLINE uint32_t color_clamp_times_256(float x)
{
return (uint32_t)(_minf(_maxf(x, 0.0f), 255.0f / 256.0f) * 256.0f);
}
//Note: this will not do the same as hardware if you put NaN in.
static INLINE uint32_t color_floats_to_rgba(float r, float g, float b, float a)
{
return
(color_clamp_times_256(r) << 0) |
(color_clamp_times_256(g) << 8) |
(color_clamp_times_256(b) << 16) |
(color_clamp_times_256(a) << 24);
}
static INLINE uint32_t color_floats_to_rgba_clean(const float *color)
{
return color_floats_to_rgba(clean_float(color[0]), clean_float(color[1]), clean_float(color[2]), clean_float(color[3]));
}
static INLINE void khrn_color_rgba_to_floats(float *floats, uint32_t rgba)
{
floats[0] = (float)((rgba >> 0) & 0xff) * (1.0f / 255.0f);
floats[1] = (float)((rgba >> 8) & 0xff) * (1.0f / 255.0f);
floats[2] = (float)((rgba >> 16) & 0xff) * (1.0f / 255.0f);
floats[3] = (float)((rgba >> 24) & 0xff) * (1.0f / 255.0f);
}
extern uint32_t khrn_color_rgba_pre(uint32_t rgba);
extern uint32_t khrn_color_rgba_unpre(uint32_t rgba);
extern uint32_t khrn_color_rgba_rz(uint32_t rgba);
extern uint32_t khrn_color_rgba_clamp_to_a(uint32_t rgba);
extern uint32_t khrn_color_rgba_s_to_lin(uint32_t rgba);
extern uint32_t khrn_color_rgba_lin_to_s(uint32_t rgba);
extern uint32_t khrn_color_rgba_to_la_lin(uint32_t rgba);
extern uint32_t khrn_color_rgba_to_la_s(uint32_t rgba);
static INLINE uint32_t khrn_color_rgba_flip(uint32_t rgba)
{
return
(((rgba >> 0) & 0xff) << 24) |
(((rgba >> 8) & 0xff) << 16) |
(((rgba >> 16) & 0xff) << 8) |
(((rgba >> 24) & 0xff) << 0);
}
extern uint32_t khrn_color_rgba_add_dither(uint32_t rgba, int r, int g, int b, int a);
extern uint32_t khrn_color_rgba_transform(uint32_t rgba, const float *color_transform);
#endif

View File

@@ -0,0 +1,180 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_INT_COMMON_H
#define KHRN_INT_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif\
#include "helpers/v3d/v3d_ver.h"
//#define KHRN_NOT_REALLY_DUALCORE // Use dual core codebase but switch master thread to vpu1
//#define KHRN_SIMPLE_MULTISAMPLE
//#define USE_CTRL_FOR_DATA
//#define GLXX_FORCE_MULTISAMPLE
//#define KHRN_COMMAND_MODE_DISPLAY /* Platforms where we need to submit updates even for single-buffered surfaces */
/* As BCG runs from cached memory, all allocations have to be the max of the CPU cache (calculated in the platform layer) and
the size of the cache line on the L3 */
#define BCG_GCACHE_LINE_SIZE 256
#ifdef _VIDEOCORE
#define KHRN_VECTOR_CORE /* have a vector core for image processing operations */
#define KHRN_HW_KICK_POWERMAN /* khrn_hw_kick() kicks the clock using powerman */
#endif
#if defined(SIMPENROSE) || defined(KHRN_CARBON)
/* for simplicity and determinism, the driver is single threaded when running
* on simpenrose and carbon */
#define KHRN_SINGLE_THREADED
#endif
#ifdef KHRN_SINGLE_THREADED
#define KHRN_LLAT_NO_THREAD
#define KHRN_WORKER_USE_LLAT
#define EGL_DISP_USE_LLAT
#else
#if !VCOS_HAVE_RTOS
#define KHRN_WORKER_USE_LLAT
#endif
#define EGL_DISP_USE_LLAT
#endif
#define KHRN_LLAT_OTHER_CORE
#ifndef V3D_LEAN
#define KHRN_WORKER_OTHER_CORE
#endif
#if defined(ANDROID)
#define GL_GET_ERROR_ASYNC /* enabled with property brcm.graphics.async_errors "true" */
#endif
#if defined(ANDROID)
#define KHDISPATCH_WORKSPACE_READAHEAD_BUFFERS 15 /* only VCHIQ */
#else
#define KHDISPATCH_WORKSPACE_READAHEAD_BUFFERS 0
#endif
#define KHDISPATCH_WORKSPACE_BUFFERS (KHDISPATCH_WORKSPACE_READAHEAD_BUFFERS + 1)
#if defined(RPC_DIRECT) || defined(ANDROID)
#include <limits.h>
#define KHDISPATCH_WORKSPACE_SIZE (0x200000 / KHDISPATCH_WORKSPACE_BUFFERS)
#else
#define KHDISPATCH_WORKSPACE_SIZE ((1024 * 1024) / KHDISPATCH_WORKSPACE_BUFFERS) /* should be a multiple of 16, todo: how big does this need to be? (vg needs 8kB) */
#endif
#define KHDISPATCH_CTRL_THRESHOLD 2032
/* todo: use v3d_ver.h stuff... */
#ifdef __BCM2708A0__
#define WORKAROUND_HW1297
#define WORKAROUND_HW1451
#define WORKAROUND_HW1632
#define WORKAROUND_HW1637
#define WORKAROUND_HW2038
#define WORKAROUND_HW2136
#define WORKAROUND_HW2187
#define WORKAROUND_HW2366
#define WORKAROUND_HW2384
#define WORKAROUND_HW2422
#define WORKAROUND_HW2479
#define WORKAROUND_HW2487
#define WORKAROUND_HW2488
#define WORKAROUND_HW2522
#define WORKAROUND_HW2781
#define KHRN_HW_SINGLE_TEXTURE_UNIT /* Only single texture unit available */
#endif
#define WORKAROUND_HW2116
#define WORKAROUND_HW2806
#define WORKAROUND_HW2885
#define WORKAROUND_HW2903
#define WORKAROUND_HW2905
#define WORKAROUND_HW2924
#if !defined(KHRN_CARBON) /* hw-2959 fixed in latest rtl... */
#define WORKAROUND_HW2959
#define WORKAROUND_HW2989
#endif
#if !V3D_VER_AT_LEAST(3,0)
#define WORKAROUND_GFXH30
#endif
#ifndef NULL
# ifdef __cplusplus
# define NULL 0
# else
# define NULL ((void *)0)
# endif
#endif
#include "interface/vcos/vcos_assert.h"
#include <string.h> /* size_t */
#ifdef _MSC_VER
#define INLINE __inline
typedef unsigned long long uint64_t;
#else
#ifdef __GNUC__
/* Just using inline doesn't work for gcc (at least on MIPS), so use the gcc attribute.
This gives a pretty decent performance boost */
#define INLINE inline __attribute__((always_inline))
#else
#define INLINE inline
#endif
#endif
#include "interface/vcos/vcos_stdbool.h"
#ifdef NDEBUG
#define verify(X) X
#else
#define verify(X) vcos_assert(X)
#endif
#define UNREACHABLE() vcos_assert(0)
#ifdef _MSC_VER
#define UNUSED(X) X
#else
#define UNUSED(X)
#endif
#ifdef NDEBUG
#define UNUSED_NDEBUG(X) UNUSED(X)
#else
#define UNUSED_NDEBUG(X)
#endif
#define KHRN_NO_SEMAPHORE 0xffffffff
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,340 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_generic_map.h"
#include "interface/khronos/common/khrn_int_util.h"
#ifndef KHRN_GENERIC_MAP_CMP_VALUE
#define KHRN_GENERIC_MAP_CMP_VALUE(x, y) (x==y)
#endif
static INLINE uint32_t hash(KHRN_GENERIC_MAP_KEY_T key, uint32_t capacity)
{
return (uint32_t)key & (capacity - 1);
}
static KHRN_GENERIC_MAP(ENTRY_T) *get_entry(KHRN_GENERIC_MAP(ENTRY_T) *base, uint32_t capacity, KHRN_GENERIC_MAP_KEY_T key)
{
uint32_t h = hash(key, capacity);
while (!KHRN_GENERIC_MAP_CMP_VALUE(base[h].value, KHRN_GENERIC_MAP_VALUE_NONE)) {
if (base[h].key == key) {
return (KHRN_GENERIC_MAP_CMP_VALUE(base[h].value, KHRN_GENERIC_MAP_VALUE_DELETED)) ? NULL : (base + h);
}
if (++h == capacity) {
h = 0;
}
}
return NULL;
}
static KHRN_GENERIC_MAP(ENTRY_T) *get_free_entry(KHRN_GENERIC_MAP(ENTRY_T) *base, uint32_t capacity, KHRN_GENERIC_MAP_KEY_T key)
{
uint32_t h = hash(key, capacity);
while ((!KHRN_GENERIC_MAP_CMP_VALUE(base[h].value, KHRN_GENERIC_MAP_VALUE_DELETED)) && (!KHRN_GENERIC_MAP_CMP_VALUE(base[h].value, KHRN_GENERIC_MAP_VALUE_NONE))) {
if (++h == capacity) {
h = 0;
}
}
return base + h;
}
static bool realloc_storage(KHRN_GENERIC_MAP(T) *map, uint32_t new_capacity)
{
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
MEM_HANDLE_T handle = map->storage;
KHRN_GENERIC_MAP(ENTRY_T) *base;
#else
KHRN_GENERIC_MAP(ENTRY_T) *base = map->storage;
#endif
uint32_t capacity = map->capacity;
uint32_t i;
/*
new map
*/
if (!khrn_generic_map(init)(map, new_capacity)) {
/* khrn_generic_map(init) fills in struct only once it is sure to succeed,
* so if we get here struct will be unmodified */
return false;
}
/*
copy entries across to new map and destroy old map
*/
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
base = (KHRN_GENERIC_MAP(ENTRY_T) *)mem_lock(handle);
#endif
for (i = 0; i != capacity; ++i) {
if ((!KHRN_GENERIC_MAP_CMP_VALUE(base[i].value, KHRN_GENERIC_MAP_VALUE_DELETED)) && (!KHRN_GENERIC_MAP_CMP_VALUE(base[i].value, KHRN_GENERIC_MAP_VALUE_NONE))) {
verify(khrn_generic_map(insert)(map, base[i].key, base[i].value)); /* khrn_generic_map(insert) can only fail if the map is too small */
#ifdef KHRN_GENERIC_MAP_RELEASE_VALUE
KHRN_GENERIC_MAP_RELEASE_VALUE(base[i].value); /* new reference added by khrn_generic_map(insert) */
#endif
}
}
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_unlock(handle);
mem_release(handle);
#else
KHRN_GENERIC_MAP_FREE(base);
#endif
return true;
}
bool khrn_generic_map(init)(KHRN_GENERIC_MAP(T) *map, uint32_t capacity)
{
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
MEM_HANDLE_T handle;
#else
KHRN_GENERIC_MAP(ENTRY_T) *base;
uint32_t i;
#endif
/*
we need (capacity - 1) > (capacity / 2) and (capacity - 1) > ((3 * capacity) / 4)
to ensure we always have at least 1 unused slot
the smallest number that satisfies these constraints is 8 (7 > 4, 7 > 6)
*/
vcos_assert(capacity >= 8);
vcos_assert(is_power_of_2(capacity)); /* hash stuff assumes this */
/*
alloc and clear storage
*/
#define STRINGIZE2(X) #X
#define STRINGIZE(X) STRINGIZE2(X) /* X will be expanded here */
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
handle = mem_alloc_ex(capacity * sizeof(KHRN_GENERIC_MAP(ENTRY_T)), alignof(KHRN_GENERIC_MAP(ENTRY_T)),
MEM_FLAG_INIT, STRINGIZE(KHRN_GENERIC_MAP(T)) ".storage", MEM_COMPACT_DISCARD); /* no term (struct containing KHRN_GENERIC_MAP(T) must call khrn_generic_map(term)()) */
if (handle == MEM_INVALID_HANDLE) {
return false;
}
/* all values already initialised to KHRN_GENERIC_MAP_VALUE_NONE */
#else
base = (KHRN_GENERIC_MAP(ENTRY_T) *)KHRN_GENERIC_MAP_ALLOC(capacity * sizeof(KHRN_GENERIC_MAP(ENTRY_T)),
STRINGIZE(KHRN_GENERIC_MAP(T)) ".storage");
if (!base) {
return false;
}
for (i = 0; i != capacity; ++i) {
base[i].value = KHRN_GENERIC_MAP_VALUE_NONE;
}
#endif
#undef STRINGIZE
#undef STRINGIZE2
/*
fill in struct (do this only once we are sure to succeed --
realloc_storage and khrn_generic_map(term) under gl object semantics rely
on this behaviour)
*/
map->entries = 0;
map->deletes = 0;
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
map->storage = handle;
#else
map->storage = base;
#endif
map->capacity = capacity;
return true;
}
/*
in KHRN_GENERIC_MAP_RELOCATABLE mode, khrn_generic_map(term) may be called:
- before init: map->storage will be MEM_INVALID_HANDLE.
- after init fails: map is unchanged.
- after term: map->storage will have been set back to MEM_INVALID_HANDLE.
*/
void khrn_generic_map(term)(KHRN_GENERIC_MAP(T) *map)
{
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
if (map->storage != MEM_INVALID_HANDLE) {
#endif
#ifdef KHRN_GENERIC_MAP_RELEASE_VALUE
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
KHRN_GENERIC_MAP(ENTRY_T) *base = (KHRN_GENERIC_MAP(ENTRY_T) *)mem_lock(map->storage);
#else
KHRN_GENERIC_MAP(ENTRY_T) *base = map->storage;
#endif
uint32_t i;
for (i = 0; i != map->capacity; ++i) {
if ((!KHRN_GENERIC_MAP_CMP_VALUE(base[i].value, KHRN_GENERIC_MAP_VALUE_DELETED)) && (!KHRN_GENERIC_MAP_CMP_VALUE(base[i].value, KHRN_GENERIC_MAP_VALUE_NONE))) {
KHRN_GENERIC_MAP_RELEASE_VALUE(base[i].value);
}
}
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_unlock(map->storage);
#endif
#endif
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_release(map->storage);
map->storage = MEM_INVALID_HANDLE;
}
#else
KHRN_GENERIC_MAP_FREE(map->storage);
#endif
}
bool khrn_generic_map(insert)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, KHRN_GENERIC_MAP_VALUE_T value)
{
uint32_t capacity = map->capacity;
KHRN_GENERIC_MAP(ENTRY_T) *entry;
vcos_assert(!KHRN_GENERIC_MAP_CMP_VALUE(value, KHRN_GENERIC_MAP_VALUE_DELETED));
vcos_assert(!KHRN_GENERIC_MAP_CMP_VALUE(value, KHRN_GENERIC_MAP_VALUE_NONE));
entry = get_entry(
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
(KHRN_GENERIC_MAP(ENTRY_T) *)mem_lock(map->storage),
#else
map->storage,
#endif
capacity, key);
if (entry) {
#ifdef KHRN_GENERIC_MAP_ACQUIRE_VALUE
KHRN_GENERIC_MAP_ACQUIRE_VALUE(value);
#endif
#ifdef KHRN_GENERIC_MAP_RELEASE_VALUE
KHRN_GENERIC_MAP_RELEASE_VALUE(entry->value);
#endif
entry->value = value;
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_unlock(map->storage);
#endif
} else {
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_unlock(map->storage);
#endif
if (map->entries > (capacity / 2)) {
capacity *= 2;
if (!realloc_storage(map, capacity)) { return false; }
} else if ((map->entries + map->deletes) > ((3 * capacity) / 4)) {
if (!realloc_storage(map, capacity)) { return false; }
}
#ifdef KHRN_GENERIC_MAP_ACQUIRE_VALUE
KHRN_GENERIC_MAP_ACQUIRE_VALUE(value);
#endif
entry = get_free_entry(
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
(KHRN_GENERIC_MAP(ENTRY_T) *)mem_lock(map->storage),
#else
map->storage,
#endif
capacity, key);
if (KHRN_GENERIC_MAP_CMP_VALUE(entry->value, KHRN_GENERIC_MAP_VALUE_DELETED)) {
vcos_assert(map->deletes > 0);
--map->deletes;
}
entry->key = key;
entry->value = value;
++map->entries;
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_unlock(map->storage);
#endif
}
return true;
}
bool khrn_generic_map(delete)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key)
{
KHRN_GENERIC_MAP(ENTRY_T) *entry = get_entry(
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
(KHRN_GENERIC_MAP(ENTRY_T) *)mem_lock(map->storage),
#else
map->storage,
#endif
map->capacity, key);
if (entry) {
#ifdef KHRN_GENERIC_MAP_RELEASE_VALUE
KHRN_GENERIC_MAP_RELEASE_VALUE(entry->value);
#endif
entry->value = KHRN_GENERIC_MAP_VALUE_DELETED;
++map->deletes;
vcos_assert(map->entries > 0);
--map->entries;
}
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_unlock(map->storage);
#endif
return !!entry;
}
uint32_t khrn_generic_map(get_count)(KHRN_GENERIC_MAP(T) *map)
{
return map->entries;
}
KHRN_GENERIC_MAP_VALUE_T khrn_generic_map(lookup)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key)
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
{
KHRN_GENERIC_MAP_VALUE_T value = khrn_generic_map(lookup_locked)(map, key, mem_lock(map->storage));
mem_unlock(map->storage);
return value;
}
KHRN_GENERIC_MAP_VALUE_T khrn_generic_map(lookup_locked)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, void *storage)
#endif
{
KHRN_GENERIC_MAP(ENTRY_T) *entry = get_entry(
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
(KHRN_GENERIC_MAP(ENTRY_T) *)storage,
#else
map->storage,
#endif
map->capacity, key);
return entry ? entry->value : KHRN_GENERIC_MAP_VALUE_NONE;
}
void khrn_generic_map(iterate)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP(CALLBACK_T) func, void *data)
{
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
KHRN_GENERIC_MAP(ENTRY_T) *base = (KHRN_GENERIC_MAP(ENTRY_T) *)mem_lock(map->storage);
#else
KHRN_GENERIC_MAP(ENTRY_T) *base = map->storage;
#endif
uint32_t i;
for (i = 0; i != map->capacity; ++i) {
if ((!KHRN_GENERIC_MAP_CMP_VALUE(base[i].value, KHRN_GENERIC_MAP_VALUE_DELETED)) && (!KHRN_GENERIC_MAP_CMP_VALUE(base[i].value, KHRN_GENERIC_MAP_VALUE_NONE))) {
func(map, base[i].key, base[i].value, data);
}
}
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
mem_unlock(map->storage);
#endif
}

View File

@@ -0,0 +1,205 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
#include "middleware/khronos/common/khrn_mem.h"
#endif
typedef struct {
KHRN_GENERIC_MAP_KEY_T key;
KHRN_GENERIC_MAP_VALUE_T value;
} KHRN_GENERIC_MAP(ENTRY_T);
typedef struct {
uint32_t entries;
uint32_t deletes;
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
MEM_HANDLE_T storage;
#else
KHRN_GENERIC_MAP(ENTRY_T) *storage;
#endif
uint32_t capacity;
} KHRN_GENERIC_MAP(T);
/*
bool khrn_generic_map(init)(KHRN_GENERIC_MAP(T) *map, uint32_t capacity)
Initialises the map
Preconditions:
map is a valid pointer to an uninitialised KHRN_GENERIC_MAP(T) structure
capacity >= 8
Postconditions:
Either:
- true is returned and the structure that map points to is valid, or
- false is returned and map is still uninitialised
*/
extern bool khrn_generic_map(init)(KHRN_GENERIC_MAP(T) *map, uint32_t capacity);
/*
void khrn_generic_map(term)(KHRN_GENERIC_MAP(T) *map)
Terminates the map
Preconditions:
map is a valid pointer to a map whose values are of type X:
- where type X does not imply any external references, or
- KHRN_GENERIC_MAP_RELEASE_VALUE releases all of these references, or
- the map is empty
Postconditions:
The structure map points to is uninitialised
*/
extern void khrn_generic_map(term)(KHRN_GENERIC_MAP(T) *map);
/*
bool khrn_generic_map(insert)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, KHRN_GENERIC_MAP_VALUE_T value)
Inserts value into map with key key. If another value is already in the map
with this key, the function will not fail; the new value replaces the old
Preconditions:
map is a valid pointer to a map whose values are of type X
value is a valid value of type X
Postconditions:
If the function succeeds:
- true is returned
- key key is now associated with value
otherwise:
- false is returned
- map is unchanged
*/
extern bool khrn_generic_map(insert)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, KHRN_GENERIC_MAP_VALUE_T value);
/*
bool khrn_generic_map(delete)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key)
If present, deletes the element identified by key from the map and returns
true. If not present, returns false
Preconditions:
map is a valid pointer to a map
Postconditions:
key is not present in map
*/
extern bool khrn_generic_map(delete)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key);
extern uint32_t khrn_generic_map(get_count)(KHRN_GENERIC_MAP(T) *map);
/*
KHRN_GENERIC_MAP_VALUE_T khrn_generic_map(lookup)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key)
Returns the element of the map identified by key, or
KHRN_GENERIC_MAP_VALUE_NONE if no such element exists in the map
Preconditions:
map is a valid pointer to a map whose elements are of type X
Postconditions:
result is either KHRN_GENERIC_MAP_VALUE_NONE or a valid value of type X
*/
extern KHRN_GENERIC_MAP_VALUE_T khrn_generic_map(lookup)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key);
/*
KHRN_GENERIC_MAP_VALUE_T khrn_generic_map(lookup_locked)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, void *storage)
Returns the element of the map identified by key, or
KHRN_GENERIC_MAP_VALUE_NONE if no such element exists in the map
Preconditions:
map is a valid pointer to a map whose elements are of type X
storage is the locked pointer to map->storage
Postconditions:
result is either KHRN_GENERIC_MAP_VALUE_NONE or a valid value of type X
*/
#ifdef KHRN_GENERIC_MAP_RELOCATABLE
extern KHRN_GENERIC_MAP_VALUE_T khrn_generic_map(lookup_locked)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, void *storage);
#endif
/*
void khrn_generic_map(iterate)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP(CALLBACK_T) func, void *data)
Runs the given callback function once for every (key, value) pair in the map.
Also passes data to the function
Implementation notes:
The iterator function is allowed to delete the element it is given, but not
modify the structure of map in any other way (eg by adding new elements)
Preconditions:
map is a valid pointer to a map of element type X
data, map satisfy P
func satisfies:
[
void func(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, KHRN_GENERIC_MAP_VALUE_T value, void *data)
Preconditions:
data, map satisfy P
value is of type X
key is a key in map
map[key] == value
Postconditions:
func does not alter map, except possibly by deleting the element it is given
value is of type Y
]
Postconditions:
func has been called on every (key, value) pair in the map
map is a valid pointer to a map of element type Y
*/
typedef void (*KHRN_GENERIC_MAP(CALLBACK_T))(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP_KEY_T key, KHRN_GENERIC_MAP_VALUE_T value, void *);
extern void khrn_generic_map(iterate)(KHRN_GENERIC_MAP(T) *map, KHRN_GENERIC_MAP(CALLBACK_T) func, void *);

View File

@@ -0,0 +1,310 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
-------------------------------------------------------------------------------
These are functions for producing 32-bit hashes for hash table lookup.
khrn_hashword(), khrn_hashlittle(), hashlittle2(), hashbig(), mix(), and final()
are externally useful functions. Routines to test the hash are included
if SELF_TEST is defined. You can use this free for any purpose. It's in
the public domain. It has no warranty.
You probably want to use khrn_hashlittle(). khrn_hashlittle() and hashbig()
hash byte arrays. khrn_hashlittle() is is faster than hashbig() on
little-endian machines. Intel and AMD are little-endian machines.
On second thought, you probably want hashlittle2(), which is identical to
khrn_hashlittle() except it returns two 32-bit hashes for the price of one.
You could implement hashbig2() if you wanted but I haven't bothered here.
If you want to find a hash of, say, exactly 7 integers, do
a = i1; b = i2; c = i3;
mix(a,b,c);
a += i4; b += i5; c += i6;
mix(a,b,c);
a += i7;
final(a,b,c);
then use c as the hash value. If you have a variable length array of
4-byte integers to hash, use khrn_hashword(). If you have a byte array (like
a character string), use khrn_hashlittle(). If you have several byte arrays, or
a mix of things, see the comments above khrn_hashlittle().
Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
then mix those integers. This is fast (you can do a lot more thorough
mixing with 12*3 instructions on 3 integers than you can with 3 instructions
on 1 byte), but shoehorning those bytes into integers efficiently is messy.
-------------------------------------------------------------------------------
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_int_hash.h" // get definitions of rot, mix and final
# define HASH_LITTLE_ENDIAN 1
# define HASH_BIG_ENDIAN 0
/*
--------------------------------------------------------------------
This works on all machines. To be useful, it requires
-- that the key be an array of uint32_t's, and
-- that the length be the number of uint32_t's in the key
The function khrn_hashword() is identical to khrn_hashlittle() on little-endian
machines, and identical to hashbig() on big-endian machines,
except that the length has to be measured in uint32_ts rather than in
bytes. khrn_hashlittle() is more complicated than khrn_hashword() only because
khrn_hashlittle() has to dance around fitting the key bytes into registers.
--------------------------------------------------------------------
*/
uint32_t khrn_hashword(
const uint32_t *k, /* the key, an array of uint32_t values */
int length, /* the length of the key, in uint32_ts */
uint32_t initval) /* the previous hash, or an arbitrary value */
{
uint32_t a,b,c;
/* Set up the internal state */
a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval;
/*------------------------------------------------- handle most of the key */
while (length > 3)
{
a += k[0];
b += k[1];
c += k[2];
mix(a,b,c);
length -= 3;
k += 3;
}
/*------------------------------------------- handle the last 3 uint32_t's */
switch(length) /* all the case statements fall through */
{
case 3 : c+=k[2];
case 2 : b+=k[1];
case 1 : a+=k[0];
final(a,b,c);
case 0: /* case 0: nothing left to add */
break;
}
/*------------------------------------------------------ report the result */
return c;
}
/*
-------------------------------------------------------------------------------
khrn_hashlittle() -- hash a variable-length key into a 32-bit value
k : the key (the unaligned variable-length array of bytes)
length : the length of the key, counting by bytes
initval : can be any 4-byte value
Returns a 32-bit value. Every bit of the key affects every bit of
the return value. Two keys differing by one or two bits will have
totally different hash values.
The best hash table sizes are powers of 2. There is no need to do
mod a prime (mod is sooo slow!). If you need less than 32 bits,
use a bitmask. For example, if you need only 10 bits, do
h = (h & hashmask(10));
In which case, the hash table should have hashsize(10) elements.
If you are hashing n strings (uint8_t **)k, do it like this:
for (i=0, h=0; i<n; ++i) h = khrn_hashlittle( k[i], len[i], h);
By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
code any way you wish, private, educational, or commercial. It's free.
Use for hash table lookup, or anything where one collision in 2^^32 is
acceptable. Do NOT use for cryptographic purposes.
-------------------------------------------------------------------------------
*/
uint32_t khrn_hashlittle( const void *key, int length, uint32_t initval)
{
uint32_t a,b,c; /* internal state */
union { const void *ptr; int i; } u; /* needed for Mac Powerbook G4 */
/* Set up the internal state */
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
b += k[1];
c += k[2];
mix(a,b,c);
length -= 12;
k += 3;
}
/*----------------------------- handle the last (probably partial) block */
/*
* "k[2]&0xffffff" actually reads beyond the end of the string, but
* then masks off the part it's not allowed to read. Because the
* string is aligned, the masked-off tail is in the same word as the
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
* noticably faster for short strings (like English words).
*/
#ifndef VALGRIND
switch(length)
{
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
case 8 : b+=k[1]; a+=k[0]; break;
case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
case 6 : b+=k[1]&0xffff; a+=k[0]; break;
case 5 : b+=k[1]&0xff; a+=k[0]; break;
case 4 : a+=k[0]; break;
case 3 : a+=k[0]&0xffffff; break;
case 2 : a+=k[0]&0xffff; break;
case 1 : a+=k[0]&0xff; break;
case 0 : return c; /* zero length strings require no mixing */
}
#else /* make valgrind happy */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[1]; a+=k[0]; break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]; break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
case 1 : a+=k8[0]; break;
case 0 : return c;
}
#endif /* !valgrind */
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
const uint8_t *k8;
/*--------------- all but last block: aligned reads and different mixing */
while (length > 12)
{
a += k[0] + (((uint32_t)k[1])<<16);
b += k[2] + (((uint32_t)k[3])<<16);
c += k[4] + (((uint32_t)k[5])<<16);
mix(a,b,c);
length -= 12;
k += 6;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=k[4];
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=k[2];
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=k[0];
break;
case 1 : a+=k8[0];
break;
case 0 : return c; /* zero length requires no mixing */
}
} else { /* need to read the key one byte at a time */
const uint8_t *k = (const uint8_t *)key;
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
a += ((uint32_t)k[1])<<8;
a += ((uint32_t)k[2])<<16;
a += ((uint32_t)k[3])<<24;
b += k[4];
b += ((uint32_t)k[5])<<8;
b += ((uint32_t)k[6])<<16;
b += ((uint32_t)k[7])<<24;
c += k[8];
c += ((uint32_t)k[9])<<8;
c += ((uint32_t)k[10])<<16;
c += ((uint32_t)k[11])<<24;
mix(a,b,c);
length -= 12;
k += 12;
}
/*-------------------------------- last block: affect all 32 bits of (c) */
switch(length) /* all the case statements fall through */
{ /* Comments to pacify Coverity */
case 12: c+=((uint32_t)k[11])<<24; /* fall through */
case 11: c+=((uint32_t)k[10])<<16; /* fall through */
case 10: c+=((uint32_t)k[9])<<8; /* fall through */
case 9 : c+=k[8]; /* fall through */
case 8 : b+=((uint32_t)k[7])<<24; /* fall through */
case 7 : b+=((uint32_t)k[6])<<16; /* fall through */
case 6 : b+=((uint32_t)k[5])<<8; /* fall through */
case 5 : b+=k[4]; /* fall through */
case 4 : a+=((uint32_t)k[3])<<24; /* fall through */
case 3 : a+=((uint32_t)k[2])<<16; /* fall through */
case 2 : a+=((uint32_t)k[1])<<8; /* fall through */
case 1 : a+=k[0];
break;
case 0 : return c;
}
}
final(a,b,c);
return c;
}

View File

@@ -0,0 +1,161 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_INT_HASH_H
#define KHRN_INT_HASH_H
/*
-------------------------------------------------------------------------------
These are functions for producing 32-bit hashes for hash table lookup.
khrn_hashword(), khrn_hashlittle(), hashlittle2(), hashbig(), mix(), and final()
are externally useful functions. Routines to test the hash are included
if SELF_TEST is defined. You can use this free for any purpose. It's in
the public domain. It has no warranty.
You probably want to use khrn_hashlittle(). khrn_hashlittle() and hashbig()
hash byte arrays. khrn_hashlittle() is is faster than hashbig() on
little-endian machines. Intel and AMD are little-endian machines.
On second thought, you probably want hashlittle2(), which is identical to
khrn_hashlittle() except it returns two 32-bit hashes for the price of one.
You could implement hashbig2() if you wanted but I haven't bothered here.
If you want to find a hash of, say, exactly 7 integers, do
a = i1; b = i2; c = i3;
mix(a,b,c);
a += i4; b += i5; c += i6;
mix(a,b,c);
a += i7;
final(a,b,c);
then use c as the hash value. If you have a variable length array of
4-byte integers to hash, use khrn_hashword(). If you have a byte array (like
a character string), use khrn_hashlittle(). If you have several byte arrays, or
a mix of things, see the comments above khrn_hashlittle().
Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
then mix those integers. This is fast (you can do a lot more thorough
mixing with 12*3 instructions on 3 integers than you can with 3 instructions
on 1 byte), but shoehorning those bytes into integers efficiently is messy.
-------------------------------------------------------------------------------
*/
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
/*
-------------------------------------------------------------------------------
mix -- mix 3 32-bit values reversibly.
This is reversible, so any information in (a,b,c) before mix() is
still in (a,b,c) after mix().
If four pairs of (a,b,c) inputs are run through mix(), or through
mix() in reverse, there are at least 32 bits of the output that
are sometimes the same for one pair and different for another pair.
This was tested for:
* pairs that differed by one bit, by two bits, in any combination
of top bits of (a,b,c), or in any combination of bottom bits of
(a,b,c).
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
satisfy this are
4 6 8 16 19 4
9 15 3 18 27 15
14 9 3 7 17 3
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
for "differ" defined as + with a one-bit base and a two-bit delta. I
used http://burtleburtle.net/bob/hash/avalanche.html to choose
the operations, constants, and arrangements of the variables.
This does not achieve avalanche. There are input bits of (a,b,c)
that fail to affect some output bits of (a,b,c), especially of a. The
most thoroughly mixed value is c, but it doesn't really even achieve
avalanche in c.
This allows some parallelism. Read-after-writes are good at doubling
the number of bits affected, so the goal of mixing pulls in the opposite
direction as the goal of parallelism. I did what I could. Rotates
seem to cost as much as shifts on every machine I could lay my hands
on, and rotates are much kinder to the top and bottom bits, so I used
rotates.
-------------------------------------------------------------------------------
*/
#define mix(a,b,c) \
do { \
a -= c; a ^= rot(c, 4); c += b; \
b -= a; b ^= rot(a, 6); a += c; \
c -= b; c ^= rot(b, 8); b += a; \
a -= c; a ^= rot(c,16); c += b; \
b -= a; b ^= rot(a,19); a += c; \
c -= b; c ^= rot(b, 4); b += a; \
} while (0)
/*
-------------------------------------------------------------------------------
final -- final mixing of 3 32-bit values (a,b,c) into c
Pairs of (a,b,c) values differing in only a few bits will usually
produce values of c that look totally different. This was tested for
* pairs that differed by one bit, by two bits, in any combination
of top bits of (a,b,c), or in any combination of bottom bits of
(a,b,c).
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
These constants passed:
14 11 25 16 4 14 24
12 14 25 16 4 14 24
and these came close:
4 8 15 26 3 22 24
10 8 15 26 3 22 24
11 8 15 26 3 22 24
-------------------------------------------------------------------------------
*/
#define final(a,b,c) \
do { \
c ^= b; c -= rot(b,14); \
a ^= c; a -= rot(c,11); \
b ^= a; b -= rot(a,25); \
c ^= b; c -= rot(b,16); \
a ^= c; a -= rot(c,4); \
b ^= a; b -= rot(a,14); \
c ^= b; c -= rot(b,24); \
} while (0)
uint32_t khrn_hashword(const uint32_t *key, int length, uint32_t initval);
uint32_t khrn_hashlittle(const void *key, int length, uint32_t initval);
#endif

View File

@@ -0,0 +1,440 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_INT_IDS_H
#define KHRN_INT_IDS_H
/*
dispatch class ids
*/
#define GLBASE_ID_11 0x1000
#define GLBASE_ID_20 0x2000
#define VGBASE_ID 0x3000
#define EGLBASE_ID 0x4000
#define KHRNMISC_ID 0x6000
#define GLBASE_ID 0x7000
#define GET_BASE_ID(x) ((x) & 0xf000)
/*
common OpenGL ES 1.1 and 2.0 dispatch ids
*/
#define GLACTIVETEXTURE_ID 0x7001
#define GLBINDBUFFER_ID 0x7002
#define GLBINDTEXTURE_ID 0x7003
#define GLBUFFERDATA_ID 0x7004
#define GLBUFFERSUBDATA_ID 0x7005
#define GLCLEAR_ID 0x7006
#define GLCLEARCOLOR_ID 0x7007
#define GLCLEARDEPTHF_ID 0x7008
#define GLCLEARSTENCIL_ID 0x700a
#define GLCOLORMASK_ID 0x700b
#define GLCOMPRESSEDTEXIMAGE2D_ID 0x700c
#define GLCOMPRESSEDTEXSUBIMAGE2D_ID 0x700d
#define GLCOPYTEXIMAGE2D_ID 0x700e
#define GLCOPYTEXSUBIMAGE2D_ID 0x700f
#define GLCULLFACE_ID 0x7010
#define GLDELETEBUFFERS_ID 0x7011
#define GLDELETETEXTURES_ID 0x7012
#define GLDEPTHFUNC_ID 0x7013
#define GLDEPTHMASK_ID 0x7014
#define GLDEPTHRANGEF_ID 0x7015
#define GLDISABLE_ID 0x7016
#define GLINTDRAWELEMENTS_ID 0x7018
#define GLENABLE_ID 0x701a
#define GLFINISH_ID 0x701b
#define GLFLUSH_ID 0x701c
#define GLFRONTFACE_ID 0x701d
#define GLGENBUFFERS_ID 0x701e
#define GLGENTEXTURES_ID 0x701f
#define GLGETBOOLEANV_ID 0x7020
#define GLGETBUFFERPARAMETERIV_ID 0x7021
#define GLGETERROR_ID 0x7022
#define GLGETFLOATV_ID 0x7023
#define GLGETINTEGERV_ID 0x7024
#define GLGETTEXPARAMETERFV_ID 0x7025
#define GLGETTEXPARAMETERIV_ID 0x7026
#define GLHINT_ID 0x7027
#define GLISBUFFER_ID 0x7028
#define GLISENABLED_ID 0x702a
#define GLISTEXTURE_ID 0x702b
#define GLLINEWIDTH_ID 0x702c
#define GLPOLYGONOFFSET_ID 0x702d
#define GLREADPIXELS_ID 0x702e
#define GLSAMPLECOVERAGE_ID 0x702f
#define GLSCISSOR_ID 0x7030
#define GLTEXIMAGE2D_ID 0x7031
#define GLTEXPARAMETERF_ID 0x7032
#define GLTEXPARAMETERI_ID 0x7033
#define GLTEXSUBIMAGE2D_ID 0x7034
#define GLVIEWPORT_ID 0x7035
#define GLINTFINDMAX_ID 0x7036
#define GLINTCACHECREATE_ID 0x7037
#define GLINTCACHEDELETE_ID 0x7038
#define GLINTCACHEDATA_ID 0x703a
#define GLINTCACHEGROW_ID 0x703b
#define GLINTCACHEUSE_ID 0x708c
#define GLBLENDFUNCSEPARATE_ID 0x708d
#define GLSTENCILFUNCSEPARATE_ID 0x708e
#define GLSTENCILMASKSEPARATE_ID 0x708f
#define GLSTENCILOPSEPARATE_ID 0x7090
#define GLEGLIMAGETARGETTEXTURE2DOES_ID 0x7091 /* GL_OES_EGL_image */
#define GLGLOBALIMAGETEXTURE2DOES_ID 0x7092 /* GL_OES_EGL_image/EGL_BRCM_global_image */
#define GLDISCARDFRAMEBUFFEREXT_ID 0x7100
/* GL_OES_framebuffer_object */
#define GLISRENDERBUFFER_ID 0x7101
#define GLBINDRENDERBUFFER_ID 0x7102
#define GLDELETERENDERBUFFERS_ID 0x7103
#define GLGENRENDERBUFFERS_ID 0x7104
#define GLRENDERBUFFERSTORAGE_ID 0x7105
#define GLGETRENDERBUFFERPARAMETERIV_ID 0x7106
#define GLISFRAMEBUFFER_ID 0x7107
#define GLBINDFRAMEBUFFER_ID 0x7108
#define GLDELETEFRAMEBUFFERS_ID 0x7109
#define GLGENFRAMEBUFFERS_ID 0x710a
#define GLCHECKFRAMEBUFFERSTATUS_ID 0x710b
#define GLFRAMEBUFFERTEXTURE2D_ID 0x710c
#define GLFRAMEBUFFERRENDERBUFFER_ID 0x710d
#define GLGETFRAMEBUFFERATTACHMENTPARAMETERIV_ID 0x710e
#define GLGENERATEMIPMAP_ID 0x710f
#define GLTEXPARAMETERFV_ID 0x7110
#define GLTEXPARAMETERIV_ID 0x7111
#define GLINSERTEVENTMARKEREXT_ID 0x7112
#define GLPUSHGROUPMARKEREXT_ID 0x7113
#define GLPOPGROUPMARKEREXT_ID 0x7114
#define TEXSUBIMAGE2DASYNC_ID 0x7115
#define GLPIXELSTOREI_ID 0x7116
#define GLINTATTRIBPOINTER_ID 0x7117
#define GLINTATTRIB_ID 0x7118
#define GLINTATTRIBENABLE_ID 0x7119
/*
OpenGL ES 1.1 specific dispatch ids
*/
#define GLALPHAFUNC_ID_11 0x1001
#define GLALPHAFUNCX_ID_11 0x1002
#define GLCLEARCOLORX_ID_11 0x1004
#define GLCLEARDEPTHX_ID_11 0x1005
#define GLCLIPPLANEF_ID_11 0x1006
#define GLCLIPPLANEX_ID_11 0x1007
//#define GLCOLORPOINTER_ID_11 0x1008
#define GLCLIENTACTIVETEXTURE_ID_11 0x1009
#define GLDEPTHRANGEX_ID_11 0x100a
#define GLFOGF_ID_11 0x100b
#define GLFOGX_ID_11 0x100c
#define GLFOGFV_ID_11 0x100d
#define GLFOGXV_ID_11 0x100e
#define GLFRUSTUMF_ID_11 0x100f
#define GLFRUSTUMX_ID_11 0x1020
#define GLGETCLIPPLANEF_ID_11 0x1021
#define GLGETCLIPPLANEX_ID_11 0x1022
#define GLGETFIXEDV_ID_11 0x1023
#define GLGETLIGHTFV_ID_11 0x1024
#define GLGETLIGHTXV_ID_11 0x1025
#define GLGETMATERIALFV_ID_11 0x1026
#define GLGETMATERIALXV_ID_11 0x1027
#define GLGETTEXENVFV_ID_11 0x1028
#define GLGETTEXENVIV_ID_11 0x102a
#define GLGETTEXENVXV_ID_11 0x102b
#define GLGETTEXPARAMETERXV_ID_11 0x102c
#define GLLIGHTF_ID_11 0x102d
#define GLLIGHTX_ID_11 0x102e
#define GLLIGHTFV_ID_11 0x102f
#define GLLIGHTXV_ID_11 0x1030
#define GLLIGHTMODELF_ID_11 0x1031
#define GLLIGHTMODELX_ID_11 0x1032
#define GLLIGHTMODELFV_ID_11 0x1033
#define GLLIGHTMODELXV_ID_11 0x1034
#define GLLINEWIDTHX_ID_11 0x1035
#define GLLOADIDENTITY_ID_11 0x1036
#define GLLOADMATRIXF_ID_11 0x1037
#define GLLOADMATRIXX_ID_11 0x1038
#define GLLOGICOP_ID_11 0x103a
#define GLMATERIALF_ID_11 0x103b
#define GLMATERIALX_ID_11 0x103c
#define GLMATERIALFV_ID_11 0x103d
#define GLMATERIALXV_ID_11 0x103e
#define GLMATRIXMODE_ID_11 0x103f
#define GLMULTMATRIXF_ID_11 0x1040
#define GLMULTMATRIXX_ID_11 0x1041
//#define GLNORMALPOINTER_ID_11 0x1042
#define GLORTHOF_ID_11 0x1043
#define GLORTHOX_ID_11 0x1044
//#define GLPIXELSTOREI_ID_11 0x1045
#define GLPOINTPARAMETERF_ID_11 0x1046
#define GLPOINTPARAMETERX_ID_11 0x1047
#define GLPOINTPARAMETERFV_ID_11 0x1048
#define GLPOINTPARAMETERXV_ID_11 0x104a
#define GLPOLYGONOFFSETX_ID_11 0x104b
#define GLPOPMATRIX_ID_11 0x104c
#define GLPUSHMATRIX_ID_11 0x104d
#define GLROTATEF_ID_11 0x104e
#define GLROTATEX_ID_11 0x104f
#define GLSAMPLECOVERAGEX_ID_11 0x1050
#define GLSCALEF_ID_11 0x1051
#define GLSCALEX_ID_11 0x1052
#define GLSHADEMODEL_ID_11 0x1053
#define GLTEXENVF_ID_11 0x1057
#define GLTEXENVI_ID_11 0x1058
#define GLTEXENVX_ID_11 0x105a
#define GLTEXENVFV_ID_11 0x105b
#define GLTEXENVIV_ID_11 0x105c
#define GLTEXENVXV_ID_11 0x105d
#define GLTEXPARAMETERX_ID_11 0x105e
#define GLTRANSLATEF_ID_11 0x105f
#define GLTRANSLATEX_ID_11 0x1060
//#define GLTEXCOORDPOINTER_ID_11 0x1061
//#define GLVERTEXPOINTER_ID_11 0x1062
//#define GLPOINTSIZEPOINTEROES_ID_11 0x1063
#define GLINTCOLOR_ID_11 0x1064
#define GLQUERYMATRIXXOES_ID_11 0x1065
#define GLTEXPARAMETERXV_ID_11 0x1067
#define GLDRAWTEXFOES_ID_11 0x1068
#define GLCURRENTPALETTEMATRIXOES_ID_11 0x1069 /* GL_OES_matrix_palette */
#define GLLOADPALETTEFROMMODELVIEWMATRIXOES_ID_11 0x1070 /* GL_OES_matrix_palette */
//#define GLMATRIXINDEXPOINTEROES_ID_11 0x1071 /* GL_OES_matrix_palette */
//#define GLWEIGHTPOINTEROES_ID_11 0x1072 /* GL_OES_matrix_palette */
/*
OpenGL ES 2.0 dispatch ids
*/
#define GLATTACHSHADER_ID_20 0x2001
#define GLBINDATTRIBLOCATION_ID_20 0x2002
#define GLBLENDCOLOR_ID_20 0x2005
#define GLBLENDEQUATIONSEPARATE_ID_20 0x2006
#define GLCOMPILESHADER_ID_20 0x200a
#define GLCREATEPROGRAM_ID_20 0x200b
#define GLCREATESHADER_ID_20 0x200c
#define GLDELETEPROGRAM_ID_20 0x200e
#define GLDELETESHADER_ID_20 0x2010
#define GLDETACHSHADER_ID_20 0x2011
#define GLGETATTRIBLOCATION_ID_20 0x2017
#define GLGETACTIVEATTRIB_ID_20 0x2018
#define GLGETACTIVEUNIFORM_ID_20 0x201a
#define GLGETATTACHEDSHADERS_ID_20 0x201b
#define GLGETPROGRAMIV_ID_20 0x201d
#define GLGETPROGRAMINFOLOG_ID_20 0x201e
#define GLGETSHADERIV_ID_20 0x2020
#define GLGETSHADERINFOLOG_ID_20 0x2021
#define GLGETSHADERSOURCE_ID_20 0x2022
#define GLGETSHADERPRECISIONFORMAT_ID_20 0x2023
#define GLGETUNIFORMFV_ID_20 0x2024
#define GLGETUNIFORMIV_ID_20 0x2025
#define GLGETUNIFORMLOCATION_ID_20 0x2026
#define GLISPROGRAM_ID_20 0x2028
#define GLISSHADER_ID_20 0x202b
#define GLLINKPROGRAM_ID_20 0x202c
//#define GLPIXELSTOREI_ID_20 0x202d
#define GLPOINTSIZE_ID_20 0x202e
#define GLSHADERSOURCE_ID_20 0x2030
#define GLTEXPARAMETERIV_ID_20 0x2034
#define GLUNIFORM1F_ID_20 0x2035
#define GLUNIFORM2F_ID_20 0x2036
#define GLUNIFORM3F_ID_20 0x2037
#define GLUNIFORM4F_ID_20 0x2038
#define GLUNIFORM1I_ID_20 0x203a
#define GLUNIFORM2I_ID_20 0x203b
#define GLUNIFORM3I_ID_20 0x203c
#define GLUNIFORM4I_ID_20 0x203d
#define GLUNIFORM1FV_ID_20 0x203e
#define GLUNIFORM2FV_ID_20 0x203f
#define GLUNIFORM3FV_ID_20 0x2040
#define GLUNIFORM4FV_ID_20 0x2041
#define GLUNIFORM1IV_ID_20 0x2042
#define GLUNIFORM2IV_ID_20 0x2043
#define GLUNIFORM3IV_ID_20 0x2044
#define GLUNIFORM4IV_ID_20 0x2045
#define GLUNIFORMMATRIX2FV_ID_20 0x2046
#define GLUNIFORMMATRIX3FV_ID_20 0x2047
#define GLUNIFORMMATRIX4FV_ID_20 0x2048
#define GLUSEPROGRAM_ID_20 0x204a
#define GLVALIDATEPROGRAM_ID_20 0x204b
//#define GLVERTEXATTRIBPOINTER_ID_20 0x204c
#define GLEGLIMAGETARGETRENDERBUFFERSTORAGEOES_ID_20 0x204d /* GL_OES_EGL_image */
#define GLGLOBALIMAGERENDERBUFFERSTORAGEOES_ID_20 0x204e /* GL_OES_EGL_image/EGL_BRCM_global_image */
/*
OpenVG dispatch ids
*/
#define VGCLEARERROR_ID 0x3000
#define VGSETERROR_ID 0x3001
#define VGGETERROR_ID 0x3002
#define VGFLUSH_ID 0x3003
#define VGFINISH_ID 0x3004
#define VGCREATESTEMS_ID 0x3005
#define VGDESTROYSTEM_ID 0x3006
#define VGSETIV_ID 0x3007
#define VGSETFV_ID 0x3008
#define VGGETFV_ID 0x3009
#define VGSETPARAMETERIV_ID 0x300a
#define VGSETPARAMETERFV_ID 0x300b
#define VGGETPARAMETERIV_ID 0x300c
#define VGLOADMATRIX_ID 0x300d
#define VGMASK_ID 0x300e
#define VGRENDERTOMASK_ID 0x300f /* vg 1.1 */
#define VGCREATEMASKLAYER_ID 0x3010 /* vg 1.1 */
#define VGDESTROYMASKLAYER_ID 0x3011 /* vg 1.1 */
#define VGFILLMASKLAYER_ID 0x3012 /* vg 1.1 */
#define VGCOPYMASK_ID 0x3013 /* vg 1.1 */
#define VGCLEAR_ID 0x3014
#define VGCREATEPATH_ID 0x3015
#define VGCLEARPATH_ID 0x3016
#define VGDESTROYPATH_ID 0x3017
#define VGREMOVEPATHCAPABILITIES_ID 0x3018
#define VGAPPENDPATH_ID 0x3019
#define VGAPPENDPATHDATA_ID 0x301a
#define VGMODIFYPATHCOORDS_ID 0x301b
#define VGTRANSFORMPATH_ID 0x301c
#define VGINTERPOLATEPATH_ID 0x301d
#define VGPATHLENGTH_ID 0x301e
#define VGPOINTALONGPATH_ID 0x301f
#define VGPATHBOUNDS_ID 0x3020
#define VGPATHTRANSFORMEDBOUNDS_ID 0x3021
#define VGDRAWPATH_ID 0x3022
#define VGCREATEPAINT_ID 0x3023
#define VGDESTROYPAINT_ID 0x3024
#define VGSETPAINT_ID 0x3025
#define VGPAINTPATTERN_ID 0x3026
#define VGCREATEIMAGE_ID 0x3027
#define VGDESTROYIMAGE_ID 0x3028
#define VGCLEARIMAGE_ID 0x3029
#define VGIMAGESUBDATA_ID 0x302a
#define VGGETIMAGESUBDATA_ID 0x302b
#define VGCHILDIMAGE_ID 0x302c
#define VGGETPARENT_ID 0x302d
#define VGCOPYIMAGE_ID 0x302e
#define VGDRAWIMAGE_ID 0x302f
#define VGSETPIXELS_ID 0x3030
#define VGWRITEPIXELS_ID 0x3031
#define VGGETPIXELS_ID 0x3032
#define VGREADPIXELS_ID 0x3033
#define VGCOPYPIXELS_ID 0x3034
#define VGCREATEFONT_ID 0x3035 /* vg 1.1 */
#define VGDESTROYFONT_ID 0x3036 /* vg 1.1 */
#define VGSETGLYPHTOPATH_ID 0x3037 /* vg 1.1 */
#define VGSETGLYPHTOIMAGE_ID 0x3038 /* vg 1.1 */
#define VGCLEARGLYPH_ID 0x3039 /* vg 1.1 */
#define VGDRAWGLYPH_ID 0x303a /* vg 1.1 */
#define VGDRAWGLYPHS_ID 0x303b /* vg 1.1 */
#define VGCOLORMATRIX_ID 0x303c
#define VGCONVOLVE_ID 0x303d
#define VGSEPARABLECONVOLVE_ID 0x303e
#define VGGAUSSIANBLUR_ID 0x303f
#define VGLOOKUP_ID 0x3040
#define VGLOOKUPSINGLE_ID 0x3041
#define VGULINE_ID 0x3042 /* vgu */
#define VGUPOLYGON_ID 0x3043 /* vgu */
#define VGURECT_ID 0x3044 /* vgu */
#define VGUROUNDRECT_ID 0x3045 /* vgu */
#define VGUELLIPSE_ID 0x3046 /* vgu */
#define VGUARC_ID 0x3047 /* vgu */
#define VGCREATEEGLIMAGETARGETKHR_ID 0x3048 /* VG_KHR_EGL_image */
#define VGCREATEIMAGEFROMGLOBALIMAGE_ID 0x3049 /* VG_KHR_EGL_image/EGL_BRCM_global_image */
/*
EGL dispatch ids
*/
#define EGLINTCREATESURFACE_ID 0x4000
#define EGLINTCREATEGLES11_ID 0x4001
#define EGLINTCREATEGLES20_ID 0x4002
#define EGLINTCREATEVG_ID 0x4003
#define EGLINTDESTROYSURFACE_ID 0x4004
#define EGLINTDESTROYGL_ID 0x4005
#define EGLINTDESTROYVG_ID 0x4006
/*#define EGLINTRESIZESURFACE_ID 0x4007*/
#define EGLINTMAKECURRENT_ID 0x4008
#define EGLINTFLUSHANDWAIT_ID 0x4009
#define EGLINTSWAPBUFFERS_ID 0x400a
#define EGLINTSELECTMIPMAP_ID 0x400b
#define EGLINTFLUSH_ID 0x400c
#define EGLINTGETCOLORDATA_ID 0x400d
#define EGLINTSETCOLORDATA_ID 0x400e
#define EGLINTBINDTEXIMAGE_ID 0x400f
#define EGLINTRELEASETEXIMAGE_ID 0x4010
#define EGLINTCREATEPBUFFERFROMVGIMAGE_ID 0x4011
#define EGLINTCREATEWRAPPEDSURFACE_ID 0x4012
#define EGLCREATEIMAGEKHR_ID 0x4013 /* EGL_KHR_image */
#define EGLDESTROYIMAGEKHR_ID 0x4014 /* EGL_KHR_image */
#define EGLINTOPENMAXILDONEMARKER_ID 0x4015 /* EGL-OpenMAX interworking (Broadcom-specific) */
#define EGLINTSWAPINTERVAL_ID 0x4016
#define EGLINTGETPROCESSMEMUSAGE_ID 0x4017 /* EGL_BRCM_mem_usage */
#define EGLINTGETGLOBALMEMUSAGE_ID 0x4018
#define EGLCREATEGLOBALIMAGEBRCM_ID 0x4019 /* EGL_BRCM_global_image */
#define EGLFILLGLOBALIMAGEBRCM_ID 0x401a /* EGL_BRCM_global_image */
#define EGLCREATECOPYGLOBALIMAGEBRCM_ID 0x401b /* EGL_BRCM_global_image */
#define EGLDESTROYGLOBALIMAGEBRCM_ID 0x401c /* EGL_BRCM_global_image */
#define EGLQUERYGLOBALIMAGEBRCM_ID 0x401d /* EGL_BRCM_global_image */
#define EGLINTCREATESYNC_ID 0x401e /* EGL_KHR_fence_sync */
#define EGLINTDESTROYSYNC_ID 0x401f /* EGL_KHR_fence_sync */
#define EGLINITPERFMONITORBRCM_ID 0x4020 /* EGL_BRCM_perf_monitor */
#define EGLTERMPERFMONITORBRCM_ID 0x4021 /* EGL_BRCM_perf_monitor */
#define EGLINTDESTROYBYPID_ID 0x4022
#define EGLINTIMAGESETCOLORDATA_ID 0x4023 /* EGL_KHR_image (client-side pixmaps etc.) */
#define EGLPERFSTATSRESETBRCM_ID 0x4024 /* EGL_BRCM_perf_stats */
#define EGLPERFSTATSGETBRCM_ID 0x4025 /* EGL_BRCM_perf_stats */
#define EGLINTCREATEENDPOINTIMAGE_ID 0x4026 /* EGL_NOK_image_endpoint */
#define EGLINTDESTROYENDPOINTIMAGE_ID 0x4027 /* EGL_NOK_image_endpoint */
#define EGLINTACQUIREENDPOINTIMAGE_ID 0x4028 /* EGL_NOK_image_endpoint */
#define EGLINITDRIVERMONITORBRCM_ID 0x4029 /* EGL_BRCM_driver_monitor */
#define EGLTERMDRIVERMONITORBRCM_ID 0x402a /* EGL_BRCM_driver_monitor */
#define EGLGETDRIVERMONITORXMLBRCM_ID 0x402b /* EGL_BRCM_driver_monitor */
#define EGLDIRECTRENDERINGPOINTER_ID 0x402c /* DIRECT_RENDERING */
#define EGLPUSHRENDERINGIMAGE_ID 0x402d /* Android GL App supportN */
#define EGLINTUPDATETEXTURE_ID 0x402e /* Android GL App supportN */
#define EGLINTCREATESYNCFENCE_ID 0x402f /* EGL_KHR_fence_sync */
/*
Miscellaneous driver control functions (not related to any particular API)
*/
#define KHRNMISCTRYUNLOAD_ID 0x6000
#define KHRNMISCBULKRXREQUIRED_ID 0x6001 /* bulk transfer client->server advance notifier */
/*
signalling length used to indicate a NULL argument
*/
#define LENGTH_SIGNAL_NULL 0xffffffff
/*
async (KHAN) channel commands
*/
#define ASYNC_COMMAND_WAIT 0
#define ASYNC_COMMAND_POST 1
#define ASYNC_COMMAND_DESTROY 2
#define ASYNC_RENDER_COMPLETE 3
#define ASYNC_ERROR_NOTIFY 4
#endif

View File

@@ -0,0 +1,299 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_int_image.h"
#include "interface/khronos/common/khrn_int_util.h"
/******************************************************************************
formats
******************************************************************************/
uint32_t khrn_image_get_bpp(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
switch (format & IMAGE_FORMAT_COMP_MASK) {
case IMAGE_FORMAT_UNCOMP:
switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) {
case IMAGE_FORMAT_1: return 1;
case IMAGE_FORMAT_4: return 4;
case IMAGE_FORMAT_8: return 8;
case IMAGE_FORMAT_16: return 16;
case IMAGE_FORMAT_24: return 24;
case IMAGE_FORMAT_32: return 32;
case IMAGE_FORMAT_64: return 64;
default: UNREACHABLE(); return 0;
}
case IMAGE_FORMAT_ETC1: return 4;
case IMAGE_FORMAT_YUYV: return 16;
default: UNREACHABLE(); return 0;
}
}
/*
returns the number of red bits in each pixel of an image of the
specified format, or zero if not an RGB or RGBA format
*/
uint32_t khrn_image_get_red_size(KHRN_IMAGE_FORMAT_T format)
{
if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_RGB)) {
switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) {
case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8;
case (IMAGE_FORMAT_24 | IMAGE_FORMAT_888): return 8;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 5;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_565): return 5;
default: UNREACHABLE(); return 0;
}
} else {
return 0;
}
}
/*
returns the number of green bits in each pixel of an image of the
specified format, or zero if not an RGB or RGBA format
*/
uint32_t khrn_image_get_green_size(KHRN_IMAGE_FORMAT_T format)
{
if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_RGB)) {
switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) {
case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8;
case (IMAGE_FORMAT_24 | IMAGE_FORMAT_888): return 8;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 5;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_565): return 6;
default: UNREACHABLE(); return 0;
}
} else {
return 0;
}
}
/*
returns the number of blue bits in each pixel of an image of the
specified format, or zero if not an RGB or RGBA format
*/
uint32_t khrn_image_get_blue_size(KHRN_IMAGE_FORMAT_T format)
{
if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_RGB)) {
switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) {
case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8;
case (IMAGE_FORMAT_24 | IMAGE_FORMAT_888): return 8;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 5;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_565): return 5;
default: UNREACHABLE(); return 0;
}
} else {
return 0;
}
}
/*
returns the number of alpha bits in each pixel of an image of the
specified format, or zero if not an alpha or RGBA format
*/
uint32_t khrn_image_get_alpha_size(KHRN_IMAGE_FORMAT_T format)
{
if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_A)) {
switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) {
case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 1;
case (IMAGE_FORMAT_16 | IMAGE_FORMAT_88): return 8;
case IMAGE_FORMAT_8: return 8;
case IMAGE_FORMAT_4: return 4;
case IMAGE_FORMAT_1: return 1;
default: UNREACHABLE(); return 0;
}
} else {
return 0;
}
}
/*
returns the number of depth bits in each pixel of an image of the
specified format, or zero if not a depth or depth+stencil format
*/
uint32_t khrn_image_get_z_size(KHRN_IMAGE_FORMAT_T format)
{
if (khrn_image_is_depth(format) && (format & IMAGE_FORMAT_Z)) {
if (format == DEPTH_32_TLBD || DEPTH_COL_64_TLBD)
return 24;
switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) {
case IMAGE_FORMAT_32: return 24;
case IMAGE_FORMAT_16: return 16;
default: UNREACHABLE(); return 0;
}
} else {
return 0;
}
}
/*
returns the number of stencil bits in each pixel of an image of the
specified format, or zero if not a depth+stencil format
*/
uint32_t khrn_image_get_stencil_size(KHRN_IMAGE_FORMAT_T format)
{
if (khrn_image_is_depth(format) && (format & IMAGE_FORMAT_STENCIL)) {
if (format == DEPTH_32_TLBD || DEPTH_COL_64_TLBD)
return 8;
vcos_assert((format & IMAGE_FORMAT_PIXEL_SIZE_MASK) == IMAGE_FORMAT_32);
return 8;
} else {
return 0;
}
}
uint32_t khrn_image_get_log2_brcm2_width(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(khrn_image_is_brcm1(format) || khrn_image_is_brcm2(format));
switch (format & IMAGE_FORMAT_COMP_MASK) {
case IMAGE_FORMAT_UNCOMP:
{
switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) {
case IMAGE_FORMAT_1: return 6;
case IMAGE_FORMAT_4: return 4;
case IMAGE_FORMAT_8: return 3;
case IMAGE_FORMAT_16: return 3;
case IMAGE_FORMAT_32: return 2;
default: UNREACHABLE(); return 0;
}
}
case IMAGE_FORMAT_ETC1: return 3;
case IMAGE_FORMAT_YUYV: return 3;
default: UNREACHABLE(); return 0;
}
}
uint32_t khrn_image_get_log2_brcm2_height(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(khrn_image_is_brcm1(format) || khrn_image_is_brcm2(format));
switch (format & IMAGE_FORMAT_COMP_MASK) {
case IMAGE_FORMAT_UNCOMP:
{
switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) {
case IMAGE_FORMAT_1: return 3;
case IMAGE_FORMAT_4: return 3;
case IMAGE_FORMAT_8: return 3;
case IMAGE_FORMAT_16: return 2;
case IMAGE_FORMAT_32: return 2;
default: UNREACHABLE(); return 0;
}
}
case IMAGE_FORMAT_ETC1: return 4;
case IMAGE_FORMAT_YUYV: return 2;
default: UNREACHABLE(); return 0;
}
}
uint32_t khrn_image_get_log2_brcm1_width(KHRN_IMAGE_FORMAT_T format)
{
return khrn_image_get_log2_brcm2_width(format) + 3;
}
uint32_t khrn_image_get_log2_brcm1_height(KHRN_IMAGE_FORMAT_T format)
{
return khrn_image_get_log2_brcm2_height(format) + 3;
}
/******************************************************************************
image handling
******************************************************************************/
uint32_t khrn_image_pad_width(KHRN_IMAGE_FORMAT_T format, uint32_t width)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
switch (format & IMAGE_FORMAT_MEM_LAYOUT_MASK) {
case IMAGE_FORMAT_RSO:
vcos_assert(!(khrn_image_get_bpp(format) & 7));
return width;
case IMAGE_FORMAT_BRCM1: return round_up(width, (uint32_t) (1 << khrn_image_get_log2_brcm1_width(format)));
case IMAGE_FORMAT_BRCM2: return round_up(width, (uint32_t) (1 << khrn_image_get_log2_brcm2_width(format)));
case IMAGE_FORMAT_BRCM4: return round_up(width, 64);
default: UNREACHABLE(); return 0;
}
}
uint32_t khrn_image_pad_height(KHRN_IMAGE_FORMAT_T format, uint32_t height)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
switch (format & IMAGE_FORMAT_MEM_LAYOUT_MASK) {
case IMAGE_FORMAT_RSO: return height;
case IMAGE_FORMAT_BRCM1: return round_up(height, (uint32_t) (1 << khrn_image_get_log2_brcm1_height(format)));
case IMAGE_FORMAT_BRCM2: return round_up(height, (uint32_t) (1 << khrn_image_get_log2_brcm2_height(format)));
case IMAGE_FORMAT_BRCM4: return round_up(height, 64);
default: UNREACHABLE(); return 0;
}
}
uint32_t khrn_image_get_stride(KHRN_IMAGE_FORMAT_T format, uint32_t width)
{
return (khrn_image_pad_width(format, width) * khrn_image_get_bpp(format)) >> 3;
}
uint32_t khrn_image_get_size(KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height)
{
uint32_t size = khrn_image_get_stride(format, width) * khrn_image_pad_height(format, height);
#ifdef WORKAROUND_HW2038
if (khrn_image_is_brcm1(format) || khrn_image_is_brcm2(format)) {
uint32_t log2_brcm2_width = khrn_image_get_log2_brcm2_width(format);
uint32_t log2_brcm2_height = khrn_image_get_log2_brcm2_height(format);
uint32_t width_in_brcm2s = (width + ((1 << log2_brcm2_width) - 1)) >> log2_brcm2_width;
uint32_t height_in_brcm2s = (height + ((1 << log2_brcm2_height) - 1)) >> log2_brcm2_height;
uint32_t hw2038_size =
((((height_in_brcm2s - 1) >> 3) << 7) +
((width_in_brcm2s - 1) >> 3) + 1) << 6;
size = _max(size, hw2038_size);
} /* else: can't bind it as a texture */
#endif
return size;
}
void khrn_image_wrap(KHRN_IMAGE_WRAP_T *wrap, KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height, int32_t stride, void *storage)
{
wrap->format = format;
wrap->width = (uint16_t)width;
wrap->height = (uint16_t)height;
wrap->stride = stride;
wrap->aux = NULL;
wrap->storage = storage;
}

View File

@@ -0,0 +1,383 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_INT_IMAGE_H
#define KHRN_INT_IMAGE_H
#include "interface/khronos/common/khrn_int_util.h"
/******************************************************************************
formats
******************************************************************************/
typedef enum {
/*
layout of KHRN_IMAGE_FORMAT_T bits
When changing this, remember to change
middleware/khronos/common/2708/khrn_image_4.inc too
*/
IMAGE_FORMAT_MEM_LAYOUT_MASK = 0x7 << 0,
IMAGE_FORMAT_MEM_LAYOUT_SHIFT = 0,
IMAGE_FORMAT_MEM_LAYOUT_BC = 3,
IMAGE_FORMAT_RSO = 0 << 0, /* raster scan order */
IMAGE_FORMAT_BRCM1 = 1 << 0,
IMAGE_FORMAT_BRCM2 = 2 << 0,
IMAGE_FORMAT_BRCM3 = 3 << 0,
IMAGE_FORMAT_BRCM4 = 4 << 0,
IMAGE_FORMAT_COMP_MASK = 0x3 << 6,
IMAGE_FORMAT_UNCOMP = 0 << 6,
IMAGE_FORMAT_ETC1 = 1 << 6,
IMAGE_FORMAT_YUYV = 3 << 6,
/* uncomp */
IMAGE_FORMAT_PIXEL_SIZE_MASK = 0x7 << 3,
IMAGE_FORMAT_PIXEL_SIZE_SHIFT = 3,
IMAGE_FORMAT_1 = 0 << 3,
IMAGE_FORMAT_4 = 1 << 3,
IMAGE_FORMAT_8 = 2 << 3,
IMAGE_FORMAT_16 = 3 << 3,
IMAGE_FORMAT_24 = 4 << 3,
IMAGE_FORMAT_32 = 5 << 3,
IMAGE_FORMAT_64 = 6 << 3,
IMAGE_FORMAT_PIXEL_TYPE_MASK = 0x3 << 8,
IMAGE_FORMAT_COLOR = 0 << 8,
IMAGE_FORMAT_PALETTE = 1 << 8,
IMAGE_FORMAT_SAMPLE = 2 << 8,
IMAGE_FORMAT_DEPTH = 3 << 8, /* packed z and stencil */
/* uncomp, color */
IMAGE_FORMAT_RGB = 1 << 10,
IMAGE_FORMAT_L = 1 << 11,
IMAGE_FORMAT_A = 1 << 12,
IMAGE_FORMAT_XBGRX = 0 << 13, /* r in low bits */
IMAGE_FORMAT_XRGBX = 1 << 13, /* r in high bits */
IMAGE_FORMAT_YUYV_STD = 0 << 13, /* Standard ordering */
IMAGE_FORMAT_YUYV_REV = 1 << 13, /* Reversed (UYVY) ordering */
IMAGE_FORMAT_AX = 0 << 14, /* alpha/x in high bits */
IMAGE_FORMAT_XA = 1 << 14, /* alpha/x in low bits */
IMAGE_FORMAT_PIXEL_LAYOUT_MASK = 0x7 << 15,
/* pixel size used to differentiate between eg 4444 and 8888 */
/* unspecified (0) means one channel occupying entire pixel */
/* IMAGE_FORMAT_32 */
IMAGE_FORMAT_8888 = 1 << 15,
/* IMAGE_FORMAT_24 */
IMAGE_FORMAT_888 = 1 << 15,
/* IMAGE_FORMAT_16 */
IMAGE_FORMAT_4444 = 1 << 15,
IMAGE_FORMAT_5551 = 2 << 15, /* (or 1555) */
IMAGE_FORMAT_565 = 3 << 15,
IMAGE_FORMAT_88 = 4 << 15,
IMAGE_FORMAT_PRE = 1 << 18, /* premultiplied (for vg) */
IMAGE_FORMAT_LIN = 1 << 19, /* linear (for vg) */
/* uncomp, depth */
IMAGE_FORMAT_Z = 1 << 10,
IMAGE_FORMAT_STENCIL = 1 << 11,
/*
some IMAGE_FORMAT_Ts
Components are listed with the most significant bits first.
On little-endian systems, it is as if a pixel was loaded as a little-endian
integer. This means they are in the *opposite* order to how they appear in memory (e.g. in ABGR_8888
format, the first byte would be the red component of the first pixel).
On big-endian systems, it is as if a pixel was loaded as a big-endian integer.
This means that the components are written in the same order that they appear in
memory (e.g. in ABGR_8888 format, the first byte would be alpha).
*/
#define IMAGE_FORMAT_PACK(A, B, C, D, E, F, G, H, I) \
(IMAGE_FORMAT_##A | IMAGE_FORMAT_##B | IMAGE_FORMAT_##C | IMAGE_FORMAT_##D | IMAGE_FORMAT_##E | \
IMAGE_FORMAT_##F | IMAGE_FORMAT_##G | IMAGE_FORMAT_##H | IMAGE_FORMAT_##I)
#define IMAGE_FORMAT__ 0
RGBA_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, A, XRGBX, XA, 8888),
BGRA_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, A, XBGRX, XA, 8888),
ARGB_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, A, XRGBX, AX, 8888),
ABGR_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, A, XBGRX, AX, 8888),
RGBX_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, _, XRGBX, XA, 8888),
BGRX_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, _, XBGRX, XA, 8888),
XRGB_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, _, XRGBX, AX, 8888),
XBGR_8888 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, COLOR , RGB, _, XBGRX, AX, 8888),
RGB_888 = IMAGE_FORMAT_PACK(_, UNCOMP, 24, COLOR , RGB, _, XRGBX, _ , 888 ),
BGR_888 = IMAGE_FORMAT_PACK(_, UNCOMP, 24, COLOR , RGB, _, XBGRX, _ , 888 ),
RGBA_4444 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XRGBX, XA, 4444),
BGRA_4444 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XBGRX, XA, 4444),
ARGB_4444 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XRGBX, AX, 4444),
ABGR_4444 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XBGRX, AX, 4444),
RGBA_5551 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XRGBX, XA, 5551),
BGRA_5551 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XBGRX, XA, 5551),
ARGB_1555 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XRGBX, AX, 5551),
ABGR_1555 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, A, XBGRX, AX, 5551),
RGB_565 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, _, XRGBX, _ , 565 ),
BGR_565 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , RGB, _, XBGRX, _ , 565 ),
LA_88 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , L , A, _ , XA, 88 ),
AL_88 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, COLOR , L , A, _ , AX, 88 ),
L_8 = IMAGE_FORMAT_PACK(_, UNCOMP, 8 , COLOR , L , _, _ , _ , _ ),
L_1 = IMAGE_FORMAT_PACK(_, UNCOMP, 1 , COLOR , L , _, _ , _ , _ ),
A_8 = IMAGE_FORMAT_PACK(_, UNCOMP, 8 , COLOR , _ , A, _ , _ , _ ),
A_4 = IMAGE_FORMAT_PACK(_, UNCOMP, 4 , COLOR , _ , A, _ , _ , _ ),
A_1 = IMAGE_FORMAT_PACK(_, UNCOMP, 1 , COLOR , _ , A, _ , _ , _ ),
PALETTE_4 = IMAGE_FORMAT_PACK(_, UNCOMP, 4 , PALETTE, _ , _, _ , _ , _ ),
SAMPLE_16 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, SAMPLE , _ , _, _ , _ , _ ),
SAMPLE_8 = IMAGE_FORMAT_PACK(_, UNCOMP, 8 , SAMPLE , _ , _, _ , _ , _ ),
DEPTH_32 = IMAGE_FORMAT_PACK(_, UNCOMP, 32, DEPTH , Z, STENCIL, _, _ , _ ),
DEPTH_16 = IMAGE_FORMAT_PACK(_, UNCOMP, 16, DEPTH , Z, _ , _, _ , _ ),
ETC1 = IMAGE_FORMAT_PACK(_, ETC1 , _ , _ , _ , _, _ , _ , _ ),
DEPTH_64 = IMAGE_FORMAT_PACK(_, UNCOMP, 64, DEPTH , Z, STENCIL, _, _ , _ ),
YUV_422 = IMAGE_FORMAT_PACK(_, YUYV , _ , _ , _ , _, YUYV_STD , _ , _ ),
YUV_422_REV = IMAGE_FORMAT_PACK(_, YUYV , _ , _ , _ , _, YUYV_REV , _ , _ ),
#undef IMAGE_FORMAT__
#undef IMAGE_FORMAT_PACK
/* texture unit formats */
ABGR_8888_TF = ABGR_8888 | IMAGE_FORMAT_BRCM1,
ARGB_8888_TF = ARGB_8888 | IMAGE_FORMAT_BRCM1,
RGBA_8888_TF = RGBA_8888 | IMAGE_FORMAT_BRCM1,
XBGR_8888_TF = XBGR_8888 | IMAGE_FORMAT_BRCM1,
XRGB_8888_TF = XRGB_8888 | IMAGE_FORMAT_BRCM1,
RGBX_8888_TF = RGBX_8888 | IMAGE_FORMAT_BRCM1,
RGBA_4444_TF = RGBA_4444 | IMAGE_FORMAT_BRCM1,
RGBA_5551_TF = RGBA_5551 | IMAGE_FORMAT_BRCM1,
RGB_565_TF = RGB_565 | IMAGE_FORMAT_BRCM1,
BGR_565_TF = BGR_565 | IMAGE_FORMAT_BRCM1,
L_8_TF = L_8 | IMAGE_FORMAT_BRCM1,
A_8_TF = A_8 | IMAGE_FORMAT_BRCM1,
AL_88_TF = AL_88 | IMAGE_FORMAT_BRCM1,
LA_88_TF = LA_88 | IMAGE_FORMAT_BRCM1,
ETC1_TF = ETC1 | IMAGE_FORMAT_BRCM1,
PALETTE_4_TF = PALETTE_4 | IMAGE_FORMAT_BRCM1,
SAMPLE_8_TF = SAMPLE_8 | IMAGE_FORMAT_BRCM1,
SAMPLE_16_TF = SAMPLE_16 | IMAGE_FORMAT_BRCM1,
L_1_TF = L_1 | IMAGE_FORMAT_BRCM1,
A_4_TF = A_4 | IMAGE_FORMAT_BRCM1,
A_1_TF = A_1 | IMAGE_FORMAT_BRCM1,
DEPTH_16_TF = DEPTH_16 | IMAGE_FORMAT_BRCM1,
DEPTH_32_TF = DEPTH_32 | IMAGE_FORMAT_BRCM1,
/* their linear T equivalents */
ABGR_8888_LT = ABGR_8888 | IMAGE_FORMAT_BRCM2,
ARGB_8888_LT = ARGB_8888 | IMAGE_FORMAT_BRCM2,
RGBA_8888_LT = RGBA_8888 | IMAGE_FORMAT_BRCM2,
XBGR_8888_LT = XBGR_8888 | IMAGE_FORMAT_BRCM2,
XRGB_8888_LT = XRGB_8888 | IMAGE_FORMAT_BRCM2,
RGBX_8888_LT = RGBX_8888 | IMAGE_FORMAT_BRCM2,
RGBA_4444_LT = RGBA_4444 | IMAGE_FORMAT_BRCM2,
RGBA_5551_LT = RGBA_5551 | IMAGE_FORMAT_BRCM2,
RGB_565_LT = RGB_565 | IMAGE_FORMAT_BRCM2,
L_8_LT = L_8 | IMAGE_FORMAT_BRCM2,
A_8_LT = A_8 | IMAGE_FORMAT_BRCM2,
AL_88_LT = AL_88 | IMAGE_FORMAT_BRCM2,
LA_88_LT = LA_88 | IMAGE_FORMAT_BRCM2,
ETC1_LT = ETC1 | IMAGE_FORMAT_BRCM2,
PALETTE_4_LT = PALETTE_4 | IMAGE_FORMAT_BRCM2,
SAMPLE_8_LT = SAMPLE_8 | IMAGE_FORMAT_BRCM2,
SAMPLE_16_LT = SAMPLE_16 | IMAGE_FORMAT_BRCM2,
L_1_LT = L_1 | IMAGE_FORMAT_BRCM2,
A_4_LT = A_4 | IMAGE_FORMAT_BRCM2,
A_1_LT = A_1 | IMAGE_FORMAT_BRCM2,
DEPTH_16_LT = DEPTH_16 | IMAGE_FORMAT_BRCM2,
DEPTH_32_LT = DEPTH_32 | IMAGE_FORMAT_BRCM2,
/* some raster order formats */
RGBA_8888_RSO = RGBA_8888 | IMAGE_FORMAT_RSO,
BGRA_8888_RSO = BGRA_8888 | IMAGE_FORMAT_RSO,
ARGB_8888_RSO = ARGB_8888 | IMAGE_FORMAT_RSO,
ABGR_8888_RSO = ABGR_8888 | IMAGE_FORMAT_RSO,
RGBX_8888_RSO = RGBX_8888 | IMAGE_FORMAT_RSO,
BGRX_8888_RSO = BGRX_8888 | IMAGE_FORMAT_RSO,
XRGB_8888_RSO = XRGB_8888 | IMAGE_FORMAT_RSO,
XBGR_8888_RSO = XBGR_8888 | IMAGE_FORMAT_RSO,
BGR_888_RSO = BGR_888 | IMAGE_FORMAT_RSO,
RGB_888_RSO = RGB_888 | IMAGE_FORMAT_RSO,
RGBA_4444_RSO = RGBA_4444 | IMAGE_FORMAT_RSO,
BGRA_4444_RSO = BGRA_4444 | IMAGE_FORMAT_RSO,
ARGB_4444_RSO = ARGB_4444 | IMAGE_FORMAT_RSO,
ABGR_4444_RSO = ABGR_4444 | IMAGE_FORMAT_RSO,
RGBA_5551_RSO = RGBA_5551 | IMAGE_FORMAT_RSO,
BGRA_5551_RSO = BGRA_5551 | IMAGE_FORMAT_RSO,
ARGB_1555_RSO = ARGB_1555 | IMAGE_FORMAT_RSO,
ABGR_1555_RSO = ABGR_1555 | IMAGE_FORMAT_RSO,
RGB_565_RSO = RGB_565 | IMAGE_FORMAT_RSO,
BGR_565_RSO = BGR_565 | IMAGE_FORMAT_RSO,
AL_88_RSO = AL_88 | IMAGE_FORMAT_RSO,
LA_88_RSO = LA_88 | IMAGE_FORMAT_RSO,
L_8_RSO = L_8 | IMAGE_FORMAT_RSO,
L_1_RSO = L_1 | IMAGE_FORMAT_RSO,
A_8_RSO = A_8 | IMAGE_FORMAT_RSO,
A_4_RSO = A_4 | IMAGE_FORMAT_RSO,
A_1_RSO = A_1 | IMAGE_FORMAT_RSO,
YUV_422_RSO = YUV_422 | IMAGE_FORMAT_RSO,
YUV_422_REV_RSO = YUV_422_REV | IMAGE_FORMAT_RSO,
ARGB_8888_PRE = ARGB_8888 | IMAGE_FORMAT_PRE,
/* TLB dump formats */
DEPTH_32_TLBD = DEPTH_32 | IMAGE_FORMAT_BRCM4,
DEPTH_COL_64_TLBD = DEPTH_64 | IMAGE_FORMAT_BRCM4,
COL_32_TLBD = BGRA_8888 | IMAGE_FORMAT_BRCM4,
IMAGE_FORMAT_INVALID = 0xffffffff
} KHRN_IMAGE_FORMAT_T;
static INLINE bool khrn_image_is_rso(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & IMAGE_FORMAT_MEM_LAYOUT_MASK) == IMAGE_FORMAT_RSO;
}
static INLINE bool khrn_image_is_brcm1(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & IMAGE_FORMAT_MEM_LAYOUT_MASK) == IMAGE_FORMAT_BRCM1;
}
static INLINE bool khrn_image_is_brcm2(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & IMAGE_FORMAT_MEM_LAYOUT_MASK) == IMAGE_FORMAT_BRCM2;
}
static INLINE KHRN_IMAGE_FORMAT_T khrn_image_to_rso_format(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (KHRN_IMAGE_FORMAT_T)((format & ~IMAGE_FORMAT_MEM_LAYOUT_MASK) | IMAGE_FORMAT_RSO);
}
static INLINE KHRN_IMAGE_FORMAT_T khrn_image_to_tf_format(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (KHRN_IMAGE_FORMAT_T)((format & ~IMAGE_FORMAT_MEM_LAYOUT_MASK) | IMAGE_FORMAT_BRCM1);
}
static INLINE KHRN_IMAGE_FORMAT_T khrn_image_to_lt_format(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (KHRN_IMAGE_FORMAT_T)((format & ~IMAGE_FORMAT_MEM_LAYOUT_MASK) | IMAGE_FORMAT_BRCM2);
}
static INLINE bool khrn_image_is_uncomp(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & IMAGE_FORMAT_COMP_MASK) == IMAGE_FORMAT_UNCOMP;
}
static INLINE bool khrn_image_is_color(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & (IMAGE_FORMAT_COMP_MASK | IMAGE_FORMAT_PIXEL_TYPE_MASK)) == (IMAGE_FORMAT_UNCOMP | IMAGE_FORMAT_COLOR);
}
static INLINE bool khrn_image_is_gray(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & (IMAGE_FORMAT_L)) != 0;
}
static INLINE bool khrn_image_is_paletted(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & (IMAGE_FORMAT_COMP_MASK | IMAGE_FORMAT_PIXEL_TYPE_MASK)) == (IMAGE_FORMAT_UNCOMP | IMAGE_FORMAT_PALETTE);
}
static INLINE bool khrn_image_is_depth(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & (IMAGE_FORMAT_COMP_MASK | IMAGE_FORMAT_PIXEL_TYPE_MASK)) == (IMAGE_FORMAT_UNCOMP | IMAGE_FORMAT_DEPTH);
}
static INLINE bool khrn_image_is_etc1(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & IMAGE_FORMAT_COMP_MASK) == IMAGE_FORMAT_ETC1;
}
static INLINE bool khrn_image_is_yuv422(KHRN_IMAGE_FORMAT_T format)
{
vcos_assert(format != IMAGE_FORMAT_INVALID);
return (format & IMAGE_FORMAT_COMP_MASK) == IMAGE_FORMAT_YUYV;
}
extern uint32_t khrn_image_get_bpp(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_red_size(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_green_size(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_blue_size(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_alpha_size(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_z_size(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_stencil_size(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_log2_brcm2_width(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_log2_brcm2_height(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_log2_brcm1_width(KHRN_IMAGE_FORMAT_T format);
extern uint32_t khrn_image_get_log2_brcm1_height(KHRN_IMAGE_FORMAT_T format);
/******************************************************************************
image handling
******************************************************************************/
typedef struct {
KHRN_IMAGE_FORMAT_T format;
uint16_t width;
uint16_t height;
int32_t stride; /* in bytes */
void *aux;
void *storage;
} KHRN_IMAGE_WRAP_T;
extern uint32_t khrn_image_pad_width(KHRN_IMAGE_FORMAT_T format, uint32_t width);
extern uint32_t khrn_image_pad_height(KHRN_IMAGE_FORMAT_T format, uint32_t height);
extern uint32_t khrn_image_get_stride(KHRN_IMAGE_FORMAT_T format, uint32_t width);
extern uint32_t khrn_image_get_size(KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height);
extern void khrn_image_wrap(KHRN_IMAGE_WRAP_T *wrap, KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height, int32_t stride, void *storage);
#endif

View File

@@ -0,0 +1,182 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_INT_MATH_H
#define KHRN_INT_MATH_H
#include "interface/khronos/common/khrn_int_util.h"
#include <math.h>
#ifndef __VIDEOCORE__ // threadsx/nucleus define LONG which clashses
#include "interface/vcos/vcos.h"
#endif
#define PI 3.1415926535897932384626433832795f
#define SQRT_2 1.4142135623730950488016887242097f
#define EPS 1.0e-10f
static INLINE float floor_(float x)
{
return floorf(x);
}
static INLINE float ceil_(float x)
{
return ceilf(x);
}
/*
Preconditions:
-
Postconditions:
returns the magnitude of x. returns +infinity if x is infinite. returns a nan
if x is nan.
*/
static INLINE float absf_(float x)
{
return (x < 0.0f) ? -x : x;
}
static INLINE float modf_(float x, float y)
{
return fmodf(x, y);
}
static INLINE void sin_cos_(float *s, float *c, float angle)
{
*s = sinf(angle);
*c = cosf(angle);
}
static INLINE float sin_(float angle)
{
return sinf(angle);
}
static INLINE float cos_(float angle)
{
return cosf(angle);
}
static INLINE float atan2_(float y, float x)
{
return atan2f(y, x);
}
extern float acos_(float x);
static INLINE float exp_(float x)
{
return expf(x);
}
extern float mod_one_(float x);
#ifdef _VIDEOCORE
#include <vc/intrinsics.h>
static INLINE float nan_recip_(float x)
{
float est = _frecip(x); /* initial estimate, accurate to ~12 bits */
return est * (2.0f - (x * est)); /* refine with newton-raphson to get accuracy to ~24 bits */
}
static INLINE float rsqrt_(float x)
{
#ifndef NDEBUG
vcos_verify(x > 0.0f);
#endif
float est = _frsqrt(x); /* initial estimate, accurate to ~12 bits */
return est * (1.5f - ((x * 0.5f) * est * est)); /* refine with newton-raphson to get accuracy to ~24 bits */
}
#else
static INLINE float nan_recip_(float x)
{
return 1.0f / x;
}
static INLINE float rsqrt_(float x)
{
#ifndef NDEBUG
vcos_verify(x > 0.0f);
#endif
return 1.0f / sqrtf(x);
}
#endif
static INLINE float recip_(float x)
{
#ifndef NDEBUG
vcos_verify(x != 0.0f);
#endif
return nan_recip_(x);
}
static INLINE bool is_nan_(float x)
{
uint32_t bits = float_to_bits(x);
return ((bits & 0x7f800000) == 0x7f800000) && /* max exponent */
(bits << 9); /* non-zero mantissa */
}
static INLINE bool nan_lt_(float x, float y)
{
return
#ifndef KHRN_NAN_COMPARISONS_CORRECT
!is_nan_(x) && !is_nan_(y) &&
#endif
(x < y);
}
static INLINE bool nan_gt_(float x, float y)
{
return
#ifndef KHRN_NAN_COMPARISONS_CORRECT
!is_nan_(x) && !is_nan_(y) &&
#endif
(x > y);
}
static INLINE bool nan_ne_(float x, float y)
{
return
#ifndef KHRN_NAN_COMPARISONS_CORRECT
!is_nan_(x) && !is_nan_(y) &&
#endif
(x != y);
}
static INLINE float sqrt_(float x)
{
vcos_assert(!nan_lt_(x, 0.0f));
return sqrtf(x);
}
#endif

View File

@@ -0,0 +1,40 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(KHRN_IMPL_STRUCT)
#define FN(type, name, args) type (*name) args;
#elif defined(KHRN_IMPL_STRUCT_INIT)
#define FN(type, name, args) name,
#else
#define FN(type, name, args) extern type name args;
#endif
FN(void, khrn_misc_startup_impl, (void))
FN(int, khrn_misc_try_unload_impl, (void))
FN(void, khrn_misc_fifo_finish_impl, (void))
FN(void, khrn_misc_rpc_flush_impl, (void))
#undef FN

View File

@@ -0,0 +1,163 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_int_util.h"
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/GLES2/gl2.h"
#include "interface/khronos/include/GLES2/gl2ext.h"
void khrn_clip_range(
int32_t *min_x0_io, int32_t *l0_io,
int32_t min_x1, int32_t l1)
{
int32_t min_x0;
int32_t l0;
int32_t max_x0;
int32_t max_x1;
vcos_assert((*l0_io >= 0) && (l1 >= 0));
min_x0 = *min_x0_io;
l0 = *l0_io;
max_x0 = _adds(min_x0, l0);
max_x1 = min_x1 + l1;
if (min_x0 < min_x1) {
min_x0 = min_x1;
}
if (max_x0 > max_x1) {
max_x0 = max_x1;
}
l0 = _max(_subs(max_x0, min_x0), 0);
*min_x0_io = (l0 == 0) ? min_x1 : min_x0;
*l0_io = l0;
}
void khrn_clip_range2(
int32_t *min_ax0_io, int32_t *min_bx0_io, int32_t *l0_io,
int32_t min_ax1, int32_t al1,
int32_t min_bx1, int32_t bl1)
{
int32_t min_ax0;
int32_t min_bx0;
int32_t l0;
int32_t max_ax0;
int32_t max_bx0;
int32_t max_ax1;
int32_t max_bx1;
vcos_assert((*l0_io >= 0) && (al1 >= 0) && (bl1 >= 0));
min_ax0 = *min_ax0_io;
min_bx0 = *min_bx0_io;
l0 = *l0_io;
l0 = _adds(_max(min_ax0, min_bx0), l0) - _max(min_ax0, min_bx0); /* clamp l0 to avoid overflow */
max_ax0 = min_ax0 + l0;
max_bx0 = min_bx0 + l0;
max_ax1 = min_ax1 + al1;
max_bx1 = min_bx1 + bl1;
/*
if any of the following _adds/_subs overflow, we will get either
min_ax0 >= max_ax0 or min_bx0 >= max_bx0, so l0 will be 0
*/
if (min_ax0 < min_ax1) {
min_bx0 = _adds(min_bx0, _subs(min_ax1, min_ax0));
min_ax0 = min_ax1;
}
if (max_ax0 > max_ax1) {
max_bx0 = _subs(max_bx0, _subs(max_ax0, max_ax1));
max_ax0 = max_ax1;
}
if (min_bx0 < min_bx1) {
min_ax0 = _adds(min_ax0, _subs(min_bx1, min_bx0));
min_bx0 = min_bx1;
}
if (max_bx0 > max_bx1) {
max_ax0 = _subs(max_ax0, _subs(max_bx0, max_bx1));
max_bx0 = max_bx1;
}
l0 = _max(_subs(max_ax0, min_ax0), 0);
vcos_assert(l0 == _max(_subs(max_bx0, min_bx0), 0));
*min_ax0_io = (l0 == 0) ? min_ax1 : min_ax0;
*min_bx0_io = (l0 == 0) ? min_bx1 : min_bx0;
*l0_io = l0;
}
void khrn_clip_rect(
int32_t *x0, int32_t *y0, int32_t *w0, int32_t *h0,
int32_t x1, int32_t y1, int32_t w1, int32_t h1)
{
khrn_clip_range(x0, w0, x1, w1);
khrn_clip_range(y0, h0, y1, h1);
}
void khrn_clip_rect2(
int32_t *ax0, int32_t *ay0, int32_t *bx0, int32_t *by0, int32_t *w0, int32_t *h0,
int32_t ax1, int32_t ay1, int32_t aw1, int32_t ah1,
int32_t bx1, int32_t by1, int32_t bw1, int32_t bh1)
{
khrn_clip_range2(ax0, bx0, w0, ax1, aw1, bx1, bw1);
khrn_clip_range2(ay0, by0, h0, ay1, ah1, by1, bh1);
}
int khrn_get_type_size(int type)
{
switch ((GLenum)type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
return 1;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_HALF_FLOAT_OES:
return 2;
case GL_FIXED:
case GL_FLOAT:
return 4;
default:
UNREACHABLE();
return 0;
}
}
#ifdef _VIDEOCORE
void khrn_barrier(void)
{
}
#endif

View File

@@ -0,0 +1,511 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_INT_UTIL_H
#define KHRN_INT_UTIL_H
#include <ctype.h>
#include <float.h>
#include <math.h>
#include "interface/khronos/common/khrn_int_common.h"
#if !defined(__VIDEOCORE__) && !defined(WIN32) // threadsx/nucleus define LONG which clashses
#include "interface/vcos/vcos.h"
#endif
/******************************************************************************
replacements for videocore intrinsics
******************************************************************************/
#ifdef _VIDEOCORE
#include <vc/intrinsics.h>
#define _minf(x,y) _min((float)(x),(float)(y))
#define _maxf(x,y) _max((float)(x),(float)(y))
#else
static INLINE int32_t _bmask(int32_t x, int32_t y)
{
return x & ((1 << (y & 0x1f)) - 1);
}
static INLINE int32_t _min(int32_t x, int32_t y)
{
return x < y ? x : y;
}
static INLINE int32_t _max(int32_t x, int32_t y)
{
return x > y ? x : y;
}
#if defined(_MSC_VER)
static INLINE int32_t _msb(uint32_t x)
{
int32_t l = -1;
if (x)
__asm {
bsr eax, x
mov l, eax
}
return l;
}
#elif defined __CC_ARM
static INLINE int32_t _msb(uint32_t x)
{
return 31 - __clz(x);
}
#elif defined(__GNUC__)
static INLINE int32_t _msb(uint32_t x)
{
return x ? (31 - __builtin_clz(x)) : -1;
}
#else
static INLINE int32_t _msb(uint32_t x) /* unsigned to get lsr */
{
int32_t msb = -1;
while (x != 0) {
++msb;
x >>= 1;
}
return msb;
}
#endif
static INLINE uint32_t _count(uint32_t x)
{
uint32_t count = 0;
while (x != 0) {
x &= x - 1;
++count;
}
return count;
}
#if defined __CC_ARM && __TARGET_ARCH_THUMB >= 4
static INLINE uint32_t _bitrev(uint32_t x, uint32_t y)
{
return __rbit(x) >> (32-y);
}
#else
static INLINE uint32_t _bitrev(uint32_t x, uint32_t y)
{
uint32_t bitrev = 0;
uint32_t i;
for (i = 0; i != y; ++i) {
bitrev |= ((x >> i) & 1) << (y - i - 1);
}
return bitrev;
}
#endif
#ifdef __CC_ARM
static INLINE int32_t _adds(int32_t x, int32_t y)
{
return __qadd(x, y);
}
static INLINE int32_t _subs(int32_t x, int32_t y)
{
return __qsub(x, y);
}
static INLINE uint32_t _ror(uint32_t x, uint32_t y)
{
return __ror(x, y);
}
#else
static INLINE int32_t _adds(int32_t x, int32_t y)
{
int32_t z = x + y;
return (y > 0) ? ((z < x) ? (int32_t)0x7fffffff : z) : ((z > x) ? (int32_t)0x80000000 : z);
}
static INLINE int32_t _subs(int32_t x, int32_t y)
{
int32_t z = x - y;
return (y > 0) ? ((z > x) ? (int32_t)0x80000000 : z) : ((z < x) ? (int32_t)0x7fffffff : z);
}
static INLINE uint32_t _ror(uint32_t x, uint32_t y)
{
return (x << (32 - y)) | (x >> y);
}
#endif // __CC_ARM
static INLINE int32_t _abs(int32_t x)
{
return x > 0 ? x : -x;
}
static INLINE float _minf(float x, float y)
{
return x < y ? x : y;
}
static INLINE float _maxf(float x, float y)
{
return x > y ? x : y;
}
#endif // !_VIDEOCORE
/******************************************************************************
misc stuff
******************************************************************************/
#define ARR_COUNT(ARR) (sizeof(ARR) / sizeof(*(ARR)))
/* sign-extend 16-bit value with range [-0x4000, 0xbfff] */
static INLINE int32_t s_ext_off16(int32_t x)
{
return ((int32_t)(int16_t)(x - 0x4000)) + 0x4000;
}
static INLINE bool is_power_of_2(uint32_t x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
static INLINE uint32_t next_power_of_2(uint32_t x)
{
return is_power_of_2(x) ? x : (uint32_t)(1 << (_msb(x) + 1));
}
static INLINE uint32_t round_up(uint32_t x, uint32_t y)
{
vcos_assert(is_power_of_2(y));
return (x + (y - 1)) & ~(y - 1);
}
static INLINE void *round_up_ptr(void *x, uint32_t y)
{
vcos_assert(is_power_of_2(y));
return (void *)(((uintptr_t)x + (uintptr_t)(y - 1)) & ~(uintptr_t)(y - 1));
}
static INLINE uint32_t mod(int32_t x, int32_t y)
{
int32_t m = x % y;
return (m < 0) ? (m + y) : m;
}
extern int khrn_get_type_size(int type /* GLenum*/);
static INLINE int find_max(int count, int size, const void *indices)
{
int i;
int32_t max = -1;
switch (size) {
case 1:
{
uint8_t *u = (uint8_t *)indices;
for (i = 0; i < count; i++)
max = _max( max, (int32_t) u[i]);
break;
}
case 2:
{
uint16_t *u = (uint16_t *)indices;
for (i = 0; i < count; i++)
max = _max( max, (int32_t) u[i]);
break;
}
default:
UNREACHABLE();
break;
}
return (int) max;
}
/******************************************************************************
for poking around inside floats (we assume ieee-754)
******************************************************************************/
typedef union {
float f;
uint32_t bits;
} KHRN_FLOAT_BITS_T;
static INLINE uint32_t float_to_bits(float f)
{
KHRN_FLOAT_BITS_T t;
t.f = f;
return t.bits;
}
static INLINE float float_from_bits(uint32_t bits)
{
KHRN_FLOAT_BITS_T t;
t.bits = bits;
return t.f;
}
/******************************************************************************
input cleaning stuff
******************************************************************************/
#include "interface/khronos/common/khrn_int_util_cr.h"
static INLINE void clean_floats(float *dst, const float *src, uint32_t count)
{
uint32_t i;
for (i = 0; i != count; ++i) {
dst[i] = clean_float(src[i]);
}
}
/******************************************************************************
float to int conversions
******************************************************************************/
static INLINE float r2ni_to_r2n_bias(float f, int32_t shift)
{
vcos_assert((shift >= -129) && (shift <= 124));
return f + float_from_bits(((127 - (shift + 2)) << 23) | 0x7fffff);
}
/*
convert float to integer value with shift
saturating, round to nearest
on videocore, we support shifts in [-32, 31]. we only need to support shifts
of 0 and 16 for client-side code
*/
static INLINE int32_t float_to_int_shift(float f, int32_t shift)
{
#ifdef _VIDEOCORE
/* floattouint is wrapping, round to negative infinity. shift should be in [-32, 31] */
vcos_assert((shift >= -32) && (shift <= 31));
f = r2ni_to_r2n_bias(f, shift);
if (f < float_from_bits((1 << 31) | ((127 + (31 - shift)) << 23))) { return 0x80000000; }
if (f > float_from_bits(((127 + (30 - shift)) << 23) | 0x7fffff)) { return 0x7fffffff; }
return _floattouint(f, shift);
#else
vcos_assert((shift >= 0) && (shift <= 31));
f *= (float)(uint32_t)(1 << shift);
f += (f < 0.0f) ? -0.49999997f : 0.49999997f; /* assume float -> int conversion is round to zero */
if (f < -2.14748365e9f) { return 0x80000000; }
if (f > 2.14748352e9f) { return 0x7fffffff; }
return (int32_t)f;
#endif
}
/*
convert float to 48-bit integer value with shift
saturating, round to nearest
this is only supported on videocore. shift should be in [-16, 31]
*/
#ifdef _VIDEOCORE
static INLINE int64_t float_to_int48_shift(float f, int32_t shift)
{
/* floattouint is wrapping, round to negative infinity. shift should be in [-32, 31] */
vcos_assert((shift >= -16) && (shift <= 31));
f = r2ni_to_r2n_bias(f, shift);
if (f < float_from_bits((1 << 31) | ((127 + (47 - shift)) << 23))) { return 0xffff800000000000ll; }
if (f > float_from_bits(((127 + (46 - shift)) << 23) | 0x7fffff)) { return 0x00007fffffffffffll; }
return ((int64_t)(int32_t)_floattouint(f, shift - 16) << 16) | _floattouint(f, shift);
}
#endif
/*
convert float to integer value
saturating, round to nearest
*/
static INLINE int32_t float_to_int(float f)
{
return float_to_int_shift(f, 0);
}
/*
convert float to integer value
saturating, round to negative inf
*/
static INLINE int32_t float_to_int_floor(float f)
{
/*
special-case handling of small negative floats
this is so we return -1 for negative denormals (which the vg cts requires)
(we shouldn't need this if the fp library/hw properly handle denormals)
*/
uint32_t u = float_to_bits(f);
if (((u & (1 << 31)) && (u + u)) && (f > -1.0f)) {
return -1;
}
f = floorf(f); /* assume float -> int conversion is round to zero */
if (f < -2.14748365e9f) { return 0x80000000; }
if (f > 2.14748352e9f) { return 0x7fffffff; }
return (int32_t)f;
}
/*
convert float to integer value
saturating, round to zero
*/
static INLINE int32_t float_to_int_zero(float f)
{
/* assume float -> int conversion is round to zero */
if (f < -2.14748365e9f) { return 0x80000000; }
if (f > 2.14748352e9f) { return 0x7fffffff; }
return (int32_t)f;
}
/*
convert float to 16.16 fixed point value
saturating, round to nearest
Khronos documentation:
If a value is so large in magnitude that it cannot be represented with the
requested type, then the nearest value representable using the requested type
is returned.
*/
static INLINE int32_t float_to_fixed(float f)
{
return float_to_int_shift(f, 16);
}
/******************************************************************************
exact float tests (in case fp library/hw don't handle denormals correctly)
******************************************************************************/
static INLINE bool floats_identical(float x, float y)
{
return float_to_bits(x) == float_to_bits(y);
}
static INLINE bool is_zero(float f)
{
uint32_t u = float_to_bits(f);
return !(u + u);
}
static INLINE bool is_le_zero(float f)
{
uint32_t u = float_to_bits(f);
return (u & (1 << 31)) || !u;
}
/******************************************************************************
alignment stuff
******************************************************************************/
#ifdef _MSC_VER
#define alignof(T) __alignof(T)
#elif defined(__CC_ARM)
#define alignof(T) __alignof__(T)
#else
#define alignof(T) (sizeof(struct { T t; char ch; }) - sizeof(T))
#endif
/*
must use both ALIGNED and ALIGN_TO...
ALIGNED(16) int align_me[10];
ALIGN_TO(align_me, 16);
*/
#ifdef _MSC_VER
#define ALIGNED(ALIGNMENT) __declspec(align(ALIGNMENT))
#define ALIGN_TO(X, ALIGNMENT)
#elif defined(__GNUC__)
#define ALIGNED(ALIGNMENT) __attribute__ ((aligned(ALIGNMENT)))
#define ALIGN_TO(X, ALIGNMENT)
#elif defined(__HIGHC__)
#define ALIGNED(ALIGMENT)
#define ALIGN_TO(X, ALIGNMENT) pragma Align_to(ALIGNMENT, X)
#else
/* leave undefined (will get error on use) */
#endif
/******************************************************************************
range/rect intersect stuff
******************************************************************************/
extern void khrn_clip_range(
int32_t *x0, int32_t *l0,
int32_t x1, int32_t l1);
extern void khrn_clip_range2(
int32_t *ax0, int32_t *bx0, int32_t *l0,
int32_t ax1, int32_t al1,
int32_t bx1, int32_t bl1);
extern void khrn_clip_rect(
int32_t *x0, int32_t *y0, int32_t *w0, int32_t *h0,
int32_t x1, int32_t y1, int32_t w1, int32_t h1);
extern void khrn_clip_rect2(
int32_t *ax0, int32_t *ay0, int32_t *bx0, int32_t *by0, int32_t *w0, int32_t *h0,
int32_t ax1, int32_t ay1, int32_t aw1, int32_t ah1,
int32_t bx1, int32_t by1, int32_t bw1, int32_t bh1);
static INLINE bool khrn_ranges_intersect(
int32_t x0, int32_t l0,
int32_t x1, int32_t l1)
{
return (x0 < (x1 + l1)) && (x1 < (x0 + l0));
}
static INLINE bool khrn_rects_intersect(
int32_t x0, int32_t y0, int32_t w0, int32_t h0,
int32_t x1, int32_t y1, int32_t w1, int32_t h1)
{
return khrn_ranges_intersect(x0, w0, x1, w1) && khrn_ranges_intersect(y0, h0, y1, h1);
}
/******************************************************************************
memory barrier
******************************************************************************/
#ifdef KHRN_SINGLE_THREADED
/* everything is done in one thread, no need for barriers */
static INLINE void khrn_barrier(void) {}
#elif defined(_VIDEOCORE)
/* don't need a real memory barrier
* extern function should do as a compiler barrier, but todo: is there a better way? */
extern void khrn_barrier(void);
#else
/* leave undefined (will get error on use) */
#endif
#endif

View File

@@ -0,0 +1,141 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
static INLINE bool clean_boolean(int b)
{
return !!b;
}
/*
clean_float(float f)
Implementation notes:
'Cleans' a floating point number by converting -INF to -FLT_MAX, INF to FLT_MAX and
any NaN to zero. Khronos spec says nothing about what happens if an unclean float is
passed to a function, so this at least guarantees reasonable behaviour.
Preconditions:
-
Postconditions:
result r is not NaN or infinite
*/
static INLINE float clean_float(float f)
{
uint32_t u = float_to_bits(f);
if (u == 0x7f800000)
return FLT_MAX;
if (u == (uint32_t)0xff800000)
return -FLT_MAX;
if ((u & 0x7f800000) == 0x7f800000)
return 0; // force NaN to zero
return f;
}
/*
clampf(float x, float l, float u)
Implementation notes:
Khronos makes frequent use of the datatype clampf, which is defined as
floating-point value clamped to [0, 1]
This function is used in many places to clamp a floating point value to lie in a range
(almost always 0..1) and also to implicitly remove any NaNs or infinities.
Preconditions:
l and u are not NaN or infinity and l <= u
Postconditions:
result r is not NaN or an infinity, and l <= r <= u
*/
static INLINE float clampf(float x, float l, float u)
{
vcos_assert(l <= u);
x = clean_float(x);
return _maxf(_minf(x, u), l);
}
/*
fixed_to_float(int f)
Implementation notes:
OpenGL ES 1.1 makes use of the datatype 'fixed' which is defined as a:
signed 2s complement 16.16 scaled integer
This function is used to convert a fixed value to its floating point equivalent, with
some loss of precision. We believe this is justified as the state tables in the spec
talk about storing all these values as type R (floating-point number).
Preconditions:
-
Postconditions:
result r is not NaN or an infinity
*/
static INLINE float fixed_to_float(int f)
{
return (float)f / 65536.0f;
}
/*
clampi(int x, int l, int u)
Implementation notes:
Preconditions:
l <= u
Postconditions:
result r satisfies l <= r <= u
*/
static INLINE int clampi(int x, int l, int u)
{
vcos_assert(l <= u);
return (int) _max(_min( (int32_t)x, (int32_t)u), (int32_t)l);
}

View File

@@ -0,0 +1,98 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_options.h"
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
KHRN_OPTIONS_T khrn_options;
/* For now, we will use environment variables for the options.
We might, at some point, want to use ini files perhaps */
static bool read_bool_option(const char *name, bool cur)
{
char *val = getenv(name);
if (val == NULL)
return cur;
if (val[0] == 't' || val[0] == 'T' || val[0] == '1')
return true;
return false;
}
static uint32_t read_uint32_option(const char *name, uint32_t cur)
{
char *val = getenv(name);
if (val == NULL)
return cur;
if (val[0] != '\0')
return atoi(val);
return 0;
}
void khrn_init_options(void)
{
/* Default values are all 0 */
memset(&khrn_options, 0, sizeof(KHRN_OPTIONS_T));
#ifndef DISABLE_OPTION_PARSING
/* Now read the options */
khrn_options.gl_error_assist = read_bool_option( "V3D_GL_ERROR_ASSIST", khrn_options.gl_error_assist);
khrn_options.double_buffer = read_bool_option( "V3D_DOUBLE_BUFFER", khrn_options.double_buffer);
khrn_options.no_bin_render_overlap = read_bool_option( "V3D_NO_BIN_RENDER_OVERLAP", khrn_options.no_bin_render_overlap);
khrn_options.reg_dump_on_lock = read_bool_option( "V3D_REG_DUMP_ON_LOCK", khrn_options.reg_dump_on_lock);
khrn_options.clif_dump_on_lock = read_bool_option( "V3D_CLIF_DUMP_ON_LOCK", khrn_options.clif_dump_on_lock);
khrn_options.force_dither_off = read_bool_option( "V3D_FORCE_DITHER_OFF", khrn_options.force_dither_off);
khrn_options.bin_block_size = read_uint32_option("V3D_BIN_BLOCK_SIZE", khrn_options.bin_block_size);
khrn_options.max_bin_blocks = read_uint32_option("V3D_MAX_BIN_BLOCKS", khrn_options.max_bin_blocks);
#endif
}
void khrn_error_assist(GLenum error, const char *func)
{
if (khrn_options.gl_error_assist && error != GL_NO_ERROR)
{
fprintf(stderr, "V3D ERROR ASSIST : ");
switch (error)
{
case GL_INVALID_ENUM : fprintf(stderr, "GL_INVALID_ENUM in %s\n", func); break;
case GL_INVALID_VALUE : fprintf(stderr, "GL_INVALID_VALUE in %s\n", func); break;
case GL_INVALID_OPERATION : fprintf(stderr, "GL_INVALID_OPERATION in %s\n", func); break;
case GL_OUT_OF_MEMORY : fprintf(stderr, "GL_OUT_OF_MEMORY in %s\n", func); break;
default : fprintf(stderr, "ERROR CODE %d in %s\n", (int)error, func); break;
}
fflush(stderr);
}
}

View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_OPTIONS_H
#define KHRN_OPTIONS_H
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/include/GLES/gl.h"
typedef struct {
bool gl_error_assist; /* Outputs useful info when the error occurs */
bool double_buffer; /* Defaults to triple-buffered */
bool no_bin_render_overlap; /* Prevent bin/render overlap */
bool reg_dump_on_lock; /* Dump h/w registers if the h/w locks-up */
bool clif_dump_on_lock; /* Dump clif file and memory on h/w lock-up */
bool force_dither_off; /* Ensure dithering is always off */
uint32_t bin_block_size; /* Set the size of binning memory blocks */
uint32_t max_bin_blocks; /* Set the maximum number of binning block in use */
} KHRN_OPTIONS_T;
extern KHRN_OPTIONS_T khrn_options;
extern void khrn_init_options(void);
extern void khrn_error_assist(GLenum error, const char *func);
#ifdef WIN32
#undef __func__
#define __func__ __FUNCTION__
#endif
#endif

View File

@@ -0,0 +1,825 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define VCOS_LOG_CATEGORY (&khrn_client_log)
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/common/khrn_int_ids.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#ifdef WANT_X
#include "X11/Xlib.h"
#endif
extern VCOS_LOG_CAT_T khrn_client_log;
extern void vc_vchi_khronos_init();
static void send_bound_pixmaps(void);
#ifdef WANT_X
static void dump_hierarchy(Window w, Window thisw, Window look, int level);
static void dump_ancestors(Window w);
#endif
//see helpers\scalerlib\scalerlib_misc.c
//int32_t scalerlib_convert_vcimage_to_display_element()
//dark blue, 1<<3 in 888
#define CHROMA_KEY_565 0x0001
//
#ifdef WANT_X
static Display *hacky_display = 0;
static XErrorHandler old_handler = (XErrorHandler) 0 ;
static int application_error_handler(Display *display, XErrorEvent *theEvent)
{
vcos_log_trace(
"Ignoring Xlib error: error code %d request code %d\n",
theEvent->error_code,
theEvent->request_code) ;
return 0 ;
}
#endif
VCOS_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int name[3], int count)
{
char buf[64];
vcos_snprintf(buf,sizeof(buf),"KhanSemaphore%08x%08x%08x", name[0], name[1], name[2]);
return vcos_named_semaphore_create(sem, buf, count);
}
uint64_t khronos_platform_get_process_id()
{
return vcos_process_id_current();
}
static bool process_attached = false;
void *platform_tls_get(PLATFORM_TLS_T tls)
{
void *ret;
if (!process_attached)
/* TODO: this isn't thread safe */
{
vcos_log_trace("Attaching process");
client_process_attach();
process_attached = true;
tls = client_tls;
vc_vchi_khronos_init();
}
ret = vcos_tls_get(tls);
if (!ret)
{
/* The problem here is that on VCFW, the first notification we get that a thread
* exists at all is when it calls an arbitrary EGL function. We need to detect this
* case and initiliase the per-thread state.
*
* On Windows this gets done in DllMain.
*/
client_thread_attach();
vcos_thread_at_exit(client_thread_detach, NULL);
ret = vcos_tls_get(tls);
}
return ret;
}
void *platform_tls_get_check(PLATFORM_TLS_T tls)
{
return vcos_tls_get(tls);
}
/* ----------------------------------------------------------------------
* workaround for broken platforms which don't detect threads exiting
* -------------------------------------------------------------------- */
void platform_hint_thread_finished()
{
/*
todo: should we do this:
vcos_thread_deregister_at_exit(client_thread_detach);
client_thread_detach();
here?
*/
}
#ifndef KHRN_PLATFORM_VCOS_NO_MALLOC
/**
Allocate memory
@param size Size in bytes of memory block to allocate
@return pointer to memory block
**/
void *khrn_platform_malloc(size_t size, const char * name)
{
return vcos_malloc(size, name);
}
/**
Free memory
@param v Pointer to memory area to free
**/
void khrn_platform_free(void *v)
{
if (v)
{
vcos_free(v);
}
}
#endif
#ifdef WANT_X
static XImage *current_ximage = NULL;
static KHRN_IMAGE_FORMAT_T ximage_to_image_format(int bits_per_pixel, unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask)
{
if (bits_per_pixel == 16 /*&& red_mask == 0xf800 && green_mask == 0x07e0 && blue_mask == 0x001f*/)
return RGB_565_RSO;
//else if (bits_per_pixel == 24 && red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff)
// return RGB_888_RSO;
else if (bits_per_pixel == 24 && red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000)
return BGR_888_RSO;
else if (bits_per_pixel == 32 /*&& red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000*/)
return ABGR_8888_RSO; //meego uses alpha channel
else if (bits_per_pixel == 32 && red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff)
return ARGB_8888_RSO;
else
{
vcos_log_warn("platform_get_pixmap_info unknown image format\n");
return IMAGE_FORMAT_INVALID;
}
}
bool platform_get_pixmap_info(EGLNativePixmapType pixmap, KHRN_IMAGE_WRAP_T *image)
{
Window r;
int x, y;
unsigned int w, h, b, d;
KHRN_IMAGE_FORMAT_T format;
XImage *xi;
XWindowAttributes attr;
Status rc;
vcos_log_trace("platform_get_pixmap_info !!!");
if (!XGetGeometry(hacky_display, (Drawable)pixmap, &r, &x, &y, &w, &h, &b, &d))
return false;
vcos_log_trace("platform_get_pixmap_info %d geometry = %d %d %d %d",(int)pixmap,
x, y, w, h);
xi = XGetImage(hacky_display, (Drawable)pixmap, 0, 0, w, h, 0xffffffff, ZPixmap);
if (xi == NULL)
return false;
vcos_log_trace("platform_get_pixmap_info ximage = %d %d %d 0x%08x %d %x %x %x",
xi->width, xi->height, xi->bytes_per_line, (uint32_t)xi->data,
xi->bits_per_pixel, (uint32_t)xi->red_mask,
(uint32_t)xi->green_mask, (uint32_t)xi->blue_mask);
format = ximage_to_image_format(xi->bits_per_pixel, xi->red_mask, xi->green_mask, xi->blue_mask);
if (format == IMAGE_FORMAT_INVALID)
{
XDestroyImage(xi);
return false;
}
image->format = format;
image->width = xi->width;
image->height = xi->height;
image->stride = xi->bytes_per_line;
image->aux = NULL;
image->storage = xi->data;
//hacking to see if this pixmap is actually the offscreen pixmap for the window that is our current surface
{
int xw, yw;
unsigned int ww, hw, bw, dw;
unsigned long pixel;
Window rw,win = (Window)CLIENT_GET_THREAD_STATE()->opengl.draw->win;
vcos_log_trace("current EGL surface win %d ", (int)win);
if(win!=0)
{
/* Install our error handler to override Xlib's termination behavior */
old_handler = XSetErrorHandler(application_error_handler) ;
XGetGeometry(hacky_display, (Drawable)win, &rw, &xw, &yw, &ww, &hw, &bw, &dw);
vcos_log_trace("%dx%d", ww, hw);
if(ww==w && hw==h)
{
//this pixmap is the same size as our current window
pixel = XGetPixel(xi,w/2,h/2);
vcos_log_trace("Pixmap centre pixel 0x%lx%s",pixel,pixel==CHROMA_KEY_565 ? "- chroma key!!" : "");
if(pixel == CHROMA_KEY_565)//the pixmap is also full of our magic chroma key colour, we want to copy the server side EGL surface.
image->aux = (void *)CLIENT_GET_THREAD_STATE()->opengl.draw->serverbuffer ;
}
(void) XSetErrorHandler(old_handler) ;
}
}
//
current_ximage = xi;
return true;
}
void khrn_platform_release_pixmap_info(EGLNativePixmapType pixmap, KHRN_IMAGE_WRAP_T *image)
{
XDestroyImage(current_ximage);
current_ximage = NULL;
}
#else
static KHRN_IMAGE_FORMAT_T convert_format(uint32_t format)
{
switch (format & ~EGL_PIXEL_FORMAT_USAGE_MASK_BRCM) {
case EGL_PIXEL_FORMAT_ARGB_8888_PRE_BRCM: return (KHRN_IMAGE_FORMAT_T)(ABGR_8888 | IMAGE_FORMAT_PRE);
case EGL_PIXEL_FORMAT_ARGB_8888_BRCM: return ABGR_8888;
case EGL_PIXEL_FORMAT_XRGB_8888_BRCM: return XBGR_8888;
case EGL_PIXEL_FORMAT_RGB_565_BRCM: return RGB_565;
case EGL_PIXEL_FORMAT_A_8_BRCM: return A_8;
default: vcos_verify(0); return (KHRN_IMAGE_FORMAT_T)0;
}
}
bool platform_get_pixmap_info(EGLNativePixmapType pixmap, KHRN_IMAGE_WRAP_T *image)
{
image->format = convert_format(((uint32_t *)pixmap)[4]);
image->width = ((uint32_t *)pixmap)[2];
image->height = ((uint32_t *)pixmap)[3];
/* can't actually access data */
image->stride = 0;
image->aux = 0;
image->storage = 0;
return image->format != 0;
}
void khrn_platform_release_pixmap_info(EGLNativePixmapType pixmap, KHRN_IMAGE_WRAP_T *image)
{
/* Nothing to do */
}
#endif
void platform_get_pixmap_server_handle(EGLNativePixmapType pixmap, uint32_t *handle)
{
handle[0] = ((uint32_t *)pixmap)[0];
handle[1] = ((uint32_t *)pixmap)[1];
}
bool platform_match_pixmap_api_support(EGLNativePixmapType pixmap, uint32_t api_support)
{
return
(!(api_support & EGL_OPENGL_BIT) || (((uint32_t *)pixmap)[4] & EGL_PIXEL_FORMAT_RENDER_GL_BRCM)) &&
(!(api_support & EGL_OPENGL_ES_BIT) || (((uint32_t *)pixmap)[4] & EGL_PIXEL_FORMAT_RENDER_GLES_BRCM)) &&
(!(api_support & EGL_OPENGL_ES2_BIT) || (((uint32_t *)pixmap)[4] & EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM)) &&
(!(api_support & EGL_OPENVG_BIT) || (((uint32_t *)pixmap)[4] & EGL_PIXEL_FORMAT_RENDER_VG_BRCM));
}
#if EGL_BRCM_global_image && EGL_KHR_image
bool platform_use_global_image_as_egl_image(uint32_t id_0, uint32_t id_1, EGLNativePixmapType pixmap, EGLint *error)
{
return true;
}
void platform_acquire_global_image(uint32_t id_0, uint32_t id_1)
{
}
void platform_release_global_image(uint32_t id_0, uint32_t id_1)
{
}
void platform_get_global_image_info(uint32_t id_0, uint32_t id_1,
uint32_t *pixel_format, uint32_t *width, uint32_t *height)
{
EGLint id[2] = {id_0, id_1};
EGLint width_height_pixel_format[3];
verify(eglQueryGlobalImageBRCM(id, width_height_pixel_format));
width_height_pixel_format[2] |=
/* this isn't right (the flags should be those passed in to
* eglCreateGlobalImageBRCM), but this stuff is just for basic testing, so
* it doesn't really matter */
EGL_PIXEL_FORMAT_RENDER_GLES_BRCM | EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM |
EGL_PIXEL_FORMAT_RENDER_VG_BRCM | EGL_PIXEL_FORMAT_VG_IMAGE_BRCM |
EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM | EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM;
if (pixel_format) { *pixel_format = width_height_pixel_format[2]; }
if (width) { *width = width_height_pixel_format[0]; }
if (height) { *height = width_height_pixel_format[1]; }
}
#endif
void platform_client_lock(void)
{
platform_mutex_acquire(&client_mutex);
}
void platform_client_release(void)
{
platform_mutex_release(&client_mutex);
}
void platform_init_rpc(struct CLIENT_THREAD_STATE *state)
{
assert(1);
}
void platform_term_rpc(struct CLIENT_THREAD_STATE *state)
{
assert(1);
}
void platform_maybe_free_process(void)
{
assert(1);
}
void platform_destroy_winhandle(void *a, uint32_t b)
{
assert(1);
}
void platform_surface_update(uint32_t handle)
{
/*
XXX This seems as good a place as any to do the client side pixmap hack.
(called from eglSwapBuffers)
*/
send_bound_pixmaps();
}
void egl_gce_win_change_image(void)
{
assert(0);
}
void platform_retrieve_pixmap_completed(EGLNativePixmapType pixmap)
{
assert(0);
}
void platform_send_pixmap_completed(EGLNativePixmapType pixmap)
{
assert(0);
}
uint32_t platform_memcmp(const void * aLeft, const void * aRight, size_t aLen)
{
return memcmp(aLeft, aRight, aLen);
}
void platform_memcpy(void * aTrg, const void * aSrc, size_t aLength)
{
memcpy(aTrg, aSrc, aLength);
}
#ifdef WANT_X
uint32_t platform_get_handle(EGLNativeWindowType win)
{
return (uint32_t)win;
}
void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
{
Window w = (Window) win;
XWindowAttributes attr;
GC gc;
Status rc = XGetWindowAttributes(hacky_display, w, &attr);
// check rc is OK and if it is (vcos_assert(rc == 0);?????)
*width = attr.width;
*height = attr.height;
*swapchain_count = 0;
/* Hackily assume if this function is called then they want to fill with GL stuff. So fill window with chromakey. */
vcos_log_trace("Calling XCreateGC %d",(int)w);
gc = XCreateGC(hacky_display, w, 0, NULL);
XSetForeground(hacky_display, gc, CHROMA_KEY_565);
vcos_log_trace("Calling XFillRectangle %d %dx%d",(int)w,attr.width, attr.height);
XFillRectangle(hacky_display, w, gc, 0, 0, attr.width, attr.height);
vcos_log_trace("Calling XFreeGC");
XFreeGC(hacky_display, gc);
vcos_log_trace("Done platform_get_dimensions");
//debugging
dump_hierarchy(attr.root, w, 0, 0);
}
#endif
#ifdef WANT_X
EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
{
if(hacky_display==0)
{
hacky_display = (Display *)display_id;
return (EGLDisplay)1;
}
else
return EGL_NO_DISPLAY;
}
#else
EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
{
if (display_id == EGL_DEFAULT_DISPLAY)
return (EGLDisplay)1;
else
return EGL_NO_DISPLAY;
}
#endif
#ifdef WANT_X
static void dump_hierarchy(Window w, Window thisw, Window look, int level)
{
Window root_dummy, parent_dummy, *children;
unsigned int i, nchildren;
XWindowAttributes attr;
XGetWindowAttributes(hacky_display, w, &attr);
XQueryTree(hacky_display, w, &root_dummy, &parent_dummy, &children, &nchildren);
for (i = 0; i < level; i++)
{
vcos_log_trace(" ");
}
vcos_log_trace( "%d %d%s%s",
attr.map_state, (int)w,
(w==look)?" <-- LOOK FOR ME!":((w==thisw)?" <-- THIS WINDOW":""),
children?"":" no children");
if (children)
{
for (i = 0; i < nchildren; i++)
{
dump_hierarchy(children[i], thisw, look, level + 1);
}
XFree(children);
}
}
static void dump_ancestors(Window w)
{
Window root_dummy, *children;
unsigned int i, nchildren;
Window grandparent,parent = w, child = 0;
unsigned int rlayer = ~0;
bool bidirectional;
vcos_log_trace("walking back up heirarchy");
while(parent)
{
bidirectional = false;
if(!XQueryTree(hacky_display, parent, &root_dummy, &grandparent, &children, &nchildren))
break;
if (children)
{
for (i = 0; i < nchildren; i++)
{
if (children[i] == child)
{
bidirectional = true;
rlayer = i;
}
}
XFree(children);
}
vcos_log_trace("%s%s%d", bidirectional ? "<" : "", (child>0) ? "->" : "", (int)parent);
child = parent;
parent = grandparent;
}
vcos_log_trace("->end");
}
uint32_t khrn_platform_get_window_position(EGLNativeWindowType win)
{
Window w = (Window) win;
Window dummy;
XWindowAttributes attr;
Window look_for_me, root_dummy, root_dummy2, parent_dummy, *children;
int x, y;
unsigned int layer, i, nchildren;
//the assumption is that windows are at the 2nd level i.e. in the below
//root_dummy/attr.root -> look_for_me -> w
vcos_log_trace("Start khrn_platform_get_window_position");
XGetWindowAttributes(hacky_display, w, &attr);
vcos_log_trace("XGetWindowAttributes");
if (attr.map_state == IsViewable)
{
XTranslateCoordinates(hacky_display, w, attr.root, 0, 0, &x, &y, &dummy);
vcos_log_trace("XTranslateCoordinates");
XQueryTree(hacky_display, w, &root_dummy, &look_for_me, &children, &nchildren);
if (children) XFree(children);
XQueryTree(hacky_display, attr.root, &root_dummy2, &parent_dummy, &children, &nchildren);
vcos_log_trace("XQueryTree");
layer = ~0;
vcos_log_trace("Dumping hierarchy %d %d (%d)", (int)w, (int)look_for_me, (int)root_dummy);
dump_hierarchy(attr.root, w, look_for_me, 0);
if (children)
{
for (i = 0; i < nchildren; i++)
{
if (children[i] == look_for_me)
layer = i;
}
XFree(children);
}
vcos_log_trace("XFree");
if (layer == ~0)
{
vcos_log_error("EGL window isn't child of root", i);
//to try and find out where this window has gone, let us walk back up the heirarchy
dump_ancestors(w);
return ~0;
}
else
{
vcos_log_trace("End khrn_platform_get_window_position - visible");
return x | y << 12 | layer << 24;
}
}
else
{
vcos_log_trace("End khrn_platform_get_window_position - invisible");
return ~0; /* Window is invisible */
}
}
#else
static int xxx_position = 0;
uint32_t khrn_platform_get_window_position(EGLNativeWindowType win)
{
return xxx_position;
}
#endif
#define NUM_PIXMAP_BINDINGS 16
static struct
{
bool used;
bool send;
EGLNativePixmapType pixmap;
EGLImageKHR egl_image;
} pixmap_binding[NUM_PIXMAP_BINDINGS];
static void set_egl_image_color_data(EGLImageKHR egl_image, KHRN_IMAGE_WRAP_T *image)
{
int line_size = (image->stride < 0) ? -image->stride : image->stride;
int lines = KHDISPATCH_WORKSPACE_SIZE / line_size;
int offset = 0;
int height = image->height;
if (khrn_image_is_tformat(image->format))
lines &= ~63;
assert(lines > 0);
while (height > 0) {
int batch = _min(lines, height);
uint32_t len = batch * line_size;
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
int adjusted_offset = (image->stride < 0) ? (offset + (batch - 1)) : offset;
RPC_CALL8_IN_BULK(eglIntImageSetColorData_impl,
thread,
EGLINTIMAGESETCOLORDATA_ID,
RPC_EGLID(egl_image),
RPC_UINT(image->format),
RPC_UINT(0),
RPC_INT(offset),
RPC_UINT(image->width),
RPC_INT(batch),
RPC_UINT(image->stride),
(const char *)image->storage + adjusted_offset * image->stride,
len);
offset += batch;
height -= batch;
}
}
static void send_bound_pixmap(int i)
{
KHRN_IMAGE_WRAP_T image;
vcos_log_trace("send_bound_pixmap %d %d", i, (int)pixmap_binding[i].egl_image);
vcos_assert(i >= 0 && i < NUM_PIXMAP_BINDINGS);
vcos_assert(pixmap_binding[i].used);
platform_get_pixmap_info(pixmap_binding[i].pixmap, &image);
set_egl_image_color_data(pixmap_binding[i].egl_image, &image);
khrn_platform_release_pixmap_info(pixmap_binding[i].pixmap, &image);
}
static void send_bound_pixmaps(void)
{
int i;
for (i = 0; i < NUM_PIXMAP_BINDINGS; i++)
{
if (pixmap_binding[i].used && pixmap_binding[i].send)
{
send_bound_pixmap(i);
}
}
}
void khrn_platform_bind_pixmap_to_egl_image(EGLNativePixmapType pixmap, EGLImageKHR egl_image, bool send)
{
int i;
for (i = 0; i < NUM_PIXMAP_BINDINGS; i++)
{
if (!pixmap_binding[i].used)
{
vcos_log_trace("khrn_platform_bind_pixmap_to_egl_image %d", i);
pixmap_binding[i].used = true;
pixmap_binding[i].pixmap = pixmap;
pixmap_binding[i].egl_image = egl_image;
pixmap_binding[i].send = send;
if(send)
send_bound_pixmap(i);
return;
}
}
vcos_assert(0); /* Not enough NUM_PIXMAP_BINDINGS? */
}
void khrn_platform_unbind_pixmap_from_egl_image(EGLImageKHR egl_image)
{
int i;
for (i = 0; i < NUM_PIXMAP_BINDINGS; i++)
{
if (pixmap_binding[i].used && pixmap_binding[i].egl_image == egl_image)
{
pixmap_binding[i].used = false;
}
}
}
#ifdef EGL_SERVER_DISPMANX
#define NUM_WIN 6
static bool have_default_dwin[NUM_WIN];
static EGL_DISPMANX_WINDOW_T default_dwin[NUM_WIN];
static EGL_DISPMANX_WINDOW_T *check_default(EGLNativeWindowType win)
{
int wid = (int)win;
if(wid>-NUM_WIN && wid <=0) {
/*
* Special identifiers indicating the default windows. Either use the
* one we've got or create a new one
* simple hack for VMCSX_VC4_1.0 release to demonstrate concurrent running of apps under linux
* win == 0 => full screen window on display 0
* win == -1 => 1/4 screen top left window on display 0
* win == -2 => 1/4 screen top right window on display 0
* win == -3 => 1/4 screen bottom left window on display 0
* win == -4 => 1/4 screen bottom right window on display 0
* win == -5 => full screen window on display 2
* it is expected that Open WFC will provide a proper mechanism in the near future
*/
wid = -wid;
if (!have_default_dwin[wid]) {
DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( (wid == 5) ? 2 : 0 );
DISPMANX_MODEINFO_T info;
vc_dispmanx_display_get_info(display, &info);
int32_t dw = info.width, dh = info.height;
DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start( 0 );
VC_DISPMANX_ALPHA_T alpha = {DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0};
VC_RECT_T dst_rect;
VC_RECT_T src_rect;
int x, y, width, height, layer;
switch(wid)
{
case 0:
x = 0; y = 0; width = dw; height = dh; layer = 0; break;
case 1:
x = 0; y = 0; width = dw/2; height = dh/2; layer = 0; break;
case 2:
x = dw/2; y = 0; width = dw/2; height = dh/2; layer = 0; break;
case 3:
x = 0; y = dh/2; width = dw/2; height = dh/2; layer = 0; break;
case 4:
x = dw/2; y = dh/2; width = dw/2; height = dh/2; layer = 0; break;
case 5:
x = 0; y = 0; width = dw; height = dh; layer = 0; break;
}
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = width << 16;
src_rect.height = height << 16;
dst_rect.x = x;
dst_rect.y = y;
dst_rect.width = width;
dst_rect.height = height;
default_dwin[wid].element = vc_dispmanx_element_add ( update, display,
layer, &dst_rect, 0/*src*/,
&src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0/*clamp*/, 0/*transform*/);
default_dwin[wid].width = width;
default_dwin[wid].height = height;
vc_dispmanx_update_submit_sync( update );
have_default_dwin[wid] = true;
}
return &default_dwin[wid];
} else
return (EGL_DISPMANX_WINDOW_T*)win;
}
void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
{
EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
vcos_assert(dwin);
vcos_assert(dwin->width < 1<<16); // sanity check
vcos_assert(dwin->height < 1<<16); // sanity check
*width = dwin->width;
*height = dwin->height;
*swapchain_count = 0;
}
uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win)
{
EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
vcos_assert(dwin);
vcos_assert(dwin->width < 1<<16); // sanity check
vcos_assert(dwin->height < 1<<16); // sanity check
return dwin->element;
}
#endif
uint32_t platform_get_color_format ( uint32_t format ) { return format; }
void platform_dequeue(EGLDisplay dpy, EGLNativeWindowType window) {}

View File

@@ -0,0 +1,503 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define VCOS_LOG_CATEGORY (&khrn_client_log)
#include "vchiq.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_int_ids.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include <string.h>
#include <stdio.h>
extern VCOS_LOG_CAT_T khrn_client_log;
static void *workspace; /* for scatter/gather bulks */
static PLATFORM_MUTEX_T mutex;
#define FOURCC_KHAN VCHIQ_MAKE_FOURCC('K', 'H', 'A', 'N')
#define FOURCC_KHRN VCHIQ_MAKE_FOURCC('K', 'H', 'R', 'N')
#define FOURCC_KHHN VCHIQ_MAKE_FOURCC('K', 'H', 'H', 'N')
static VCHIQ_INSTANCE_T khrn_vchiq_instance;
static VCHIQ_SERVICE_HANDLE_T vchiq_khan_service;
static VCHIQ_SERVICE_HANDLE_T vchiq_khrn_service;
static VCHIQ_SERVICE_HANDLE_T vchiq_khhn_service;
static VCHIU_QUEUE_T khrn_queue;
static VCHIU_QUEUE_T khhn_queue;
static VCOS_EVENT_T bulk_event;
VCHIQ_STATUS_T khrn_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
{
switch (reason) {
case VCHIQ_MESSAGE_AVAILABLE:
vchiu_queue_push(&khrn_queue, header);
break;
case VCHIQ_BULK_TRANSMIT_DONE:
case VCHIQ_BULK_RECEIVE_DONE:
vcos_event_signal(&bulk_event);
break;
case VCHIQ_SERVICE_OPENED:
case VCHIQ_SERVICE_CLOSED:
case VCHIQ_BULK_TRANSMIT_ABORTED:
case VCHIQ_BULK_RECEIVE_ABORTED:
UNREACHABLE(); /* not implemented */
}
return VCHIQ_SUCCESS;
}
VCHIQ_STATUS_T khhn_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
{
switch (reason) {
case VCHIQ_MESSAGE_AVAILABLE:
vchiu_queue_push(&khhn_queue, header);
break;
case VCHIQ_BULK_TRANSMIT_DONE:
case VCHIQ_BULK_RECEIVE_DONE:
vcos_event_signal(&bulk_event);
break;
case VCHIQ_SERVICE_OPENED:
case VCHIQ_SERVICE_CLOSED:
case VCHIQ_BULK_TRANSMIT_ABORTED:
case VCHIQ_BULK_RECEIVE_ABORTED:
UNREACHABLE(); /* not implemented */
}
return VCHIQ_SUCCESS;
}
VCHIQ_STATUS_T khan_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
{
switch (reason) {
case VCHIQ_MESSAGE_AVAILABLE:
{
int32_t *data = (int32_t *) header->data;
int32_t command = data[0];
int32_t *msg = &data[1];
vcos_assert(header->size == 16);
// TODO should be able to remove this eventually.
// If incoming message is not addressed to this process, then ignore it.
// Correct process should then pick it up.
uint64_t pid = khronos_platform_get_process_id();
if((msg[0] != (uint32_t) pid) || (msg[1] != (uint32_t) (pid >> 32)))
{
printf("khan_callback: message for wrong process; pid = %X, msg pid = %X\n",
(uint32_t) pid, msg[0]);
return VCHIQ_SUCCESS;
} // if
if (command == ASYNC_COMMAND_DESTROY)
{
/* todo: destroy */
}
else
{
PLATFORM_SEMAPHORE_T sem;
if (khronos_platform_semaphore_create(&sem, msg, 1) == KHR_SUCCESS)
{
switch (command) {
case ASYNC_COMMAND_WAIT:
khronos_platform_semaphore_acquire(&sem);
break;
case ASYNC_COMMAND_POST:
khronos_platform_semaphore_release(&sem);
break;
default:
vcos_assert_msg(0, "khan_callback: unknown message type");
break;
}
khronos_platform_semaphore_destroy(&sem);
}
} // else
vchiq_release_message(handle, header);
break;
}
case VCHIQ_BULK_TRANSMIT_DONE:
case VCHIQ_BULK_RECEIVE_DONE:
UNREACHABLE();
break;
case VCHIQ_SERVICE_OPENED:
vcos_assert_msg(0, "khan_callback: VCHIQ_SERVICE_OPENED");
break;
case VCHIQ_SERVICE_CLOSED:
vcos_assert_msg(0, "khan_callback: VCHIQ_SERVICE_CLOSED");
break;
case VCHIQ_BULK_TRANSMIT_ABORTED:
case VCHIQ_BULK_RECEIVE_ABORTED:
default:
UNREACHABLE(); /* not implemented */
}
return VCHIQ_SUCCESS;
}
void vc_vchi_khronos_init()
{
VCOS_STATUS_T status = vcos_event_create(&bulk_event, NULL);
UNUSED_NDEBUG(status);
vcos_assert(status == VCOS_SUCCESS);
if (vchiq_initialise(&khrn_vchiq_instance) != VCHIQ_SUCCESS)
{
vcos_log_error("* failed to open vchiq device");
exit(1);
}
vcos_log_trace("gldemo: connecting");
if (vchiq_connect(khrn_vchiq_instance) != VCHIQ_SUCCESS)
{
vcos_log_error("* failed to connect");
exit(1);
}
if (vchiq_open_service(khrn_vchiq_instance, FOURCC_KHAN, khan_callback, NULL, &vchiq_khan_service) != VCHIQ_SUCCESS ||
vchiq_open_service(khrn_vchiq_instance, FOURCC_KHRN, khrn_callback, NULL, &vchiq_khrn_service) != VCHIQ_SUCCESS ||
vchiq_open_service(khrn_vchiq_instance, FOURCC_KHHN, khhn_callback, NULL, &vchiq_khhn_service) != VCHIQ_SUCCESS)
{
vcos_log_error("* failed to add service - already in use?");
exit(1);
}
vchiu_queue_init(&khrn_queue, 64);
vchiu_queue_init(&khhn_queue, 64);
vcos_log_trace("gldemo: connected");
/*
attach to process (there's just one)
*/
// bool success = client_process_attach();
// vcos_assert(success);
}
bool khclient_rpc_init(void)
{
workspace = NULL;
return platform_mutex_create(&mutex) == KHR_SUCCESS;
}
void rpc_term(void)
{
if (workspace) { khrn_platform_free(workspace); }
platform_mutex_destroy(&mutex);
}
static VCHIQ_SERVICE_HANDLE_T get_handle(CLIENT_THREAD_STATE_T *thread)
{
VCHIQ_SERVICE_HANDLE_T result = (thread->high_priority ? vchiq_khhn_service : vchiq_khrn_service);
return result;
}
static VCHIU_QUEUE_T *get_queue(CLIENT_THREAD_STATE_T *thread)
{
return thread->high_priority ? &khhn_queue : &khrn_queue;
}
static void check_workspace(uint32_t size)
{
/* todo: find a better way to handle scatter/gather bulks */
vcos_assert(size <= KHDISPATCH_WORKSPACE_SIZE);
if (!workspace) {
workspace = khrn_platform_malloc(KHDISPATCH_WORKSPACE_SIZE, "rpc_workspace");
vcos_assert(workspace);
}
}
static void merge_flush(CLIENT_THREAD_STATE_T *thread)
{
vcos_log_trace("merge_flush start");
vcos_assert(thread->merge_pos >= CLIENT_MAKE_CURRENT_SIZE);
/*
don't transmit just a make current -- in the case that there is only a
make current in the merge buffer, we have already sent a control message
for the rpc call (and with it a make current) and own the big lock
*/
if (thread->merge_pos > CLIENT_MAKE_CURRENT_SIZE) {
VCHIQ_ELEMENT_T element;
rpc_begin(thread);
element.data = thread->merge_buffer;
element.size = thread->merge_pos;
VCHIQ_STATUS_T success = vchiq_queue_message(get_handle(thread), &element, 1);
UNUSED_NDEBUG(success);
vcos_assert(success == VCHIQ_SUCCESS);
thread->merge_pos = 0;
client_send_make_current(thread);
vcos_assert(thread->merge_pos == CLIENT_MAKE_CURRENT_SIZE);
rpc_end(thread);
}
vcos_log_trace( "merge_flush end");
}
void rpc_flush(CLIENT_THREAD_STATE_T *thread)
{
merge_flush(thread);
}
void rpc_high_priority_begin(CLIENT_THREAD_STATE_T *thread)
{
vcos_assert(!thread->high_priority);
merge_flush(thread);
thread->high_priority = true;
}
void rpc_high_priority_end(CLIENT_THREAD_STATE_T *thread)
{
vcos_assert(thread->high_priority);
merge_flush(thread);
thread->high_priority = false;
}
uint32_t rpc_send_ctrl_longest(CLIENT_THREAD_STATE_T *thread, uint32_t len_min)
{
uint32_t len = MERGE_BUFFER_SIZE - thread->merge_pos;
if (len < len_min) {
len = MERGE_BUFFER_SIZE - CLIENT_MAKE_CURRENT_SIZE;
}
return len;
}
void rpc_send_ctrl_begin(CLIENT_THREAD_STATE_T *thread, uint32_t len)
{
//CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
vcos_assert(len == rpc_pad_ctrl(len));
if ((thread->merge_pos + len) > MERGE_BUFFER_SIZE) {
merge_flush(thread);
}
thread->merge_end = thread->merge_pos + len;
}
void rpc_send_ctrl_write(CLIENT_THREAD_STATE_T *thread, const uint32_t in[], uint32_t len) /* len bytes read, rpc_pad_ctrl(len) bytes written */
{
//CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
memcpy(thread->merge_buffer + thread->merge_pos, in, len);
thread->merge_pos += rpc_pad_ctrl(len);
vcos_assert(thread->merge_pos <= MERGE_BUFFER_SIZE);
}
void rpc_send_ctrl_end(CLIENT_THREAD_STATE_T *thread)
{
//CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
vcos_assert(thread->merge_pos == thread->merge_end);
}
static void send_bulk(CLIENT_THREAD_STATE_T *thread, const void *in, uint32_t len)
{
if (len <= KHDISPATCH_CTRL_THRESHOLD) {
VCHIQ_ELEMENT_T element;
element.data = in;
element.size = len;
VCHIQ_STATUS_T vchiq_status = vchiq_queue_message(get_handle(thread), &element, 1);
UNUSED_NDEBUG(vchiq_status);
vcos_assert(vchiq_status == VCHIQ_SUCCESS);
} else {
VCHIQ_STATUS_T vchiq_status = vchiq_queue_bulk_transmit(get_handle(thread), in, rpc_pad_bulk(len), NULL);
UNUSED_NDEBUG(vchiq_status);
vcos_assert(vchiq_status == VCHIQ_SUCCESS);
VCOS_STATUS_T vcos_status = vcos_event_wait(&bulk_event);
UNUSED_NDEBUG(vcos_status);
vcos_assert(vcos_status == VCOS_SUCCESS);
}
}
static void recv_bulk(CLIENT_THREAD_STATE_T *thread, void *out, uint32_t len)
{
if (len <= KHDISPATCH_CTRL_THRESHOLD) {
VCHIQ_HEADER_T *header = vchiu_queue_pop(get_queue(thread));
vcos_assert(header->size == len);
memcpy(out, header->data, len);
vchiq_release_message(get_handle(thread), header);
} else {
VCHIQ_STATUS_T vchiq_status = vchiq_queue_bulk_receive(get_handle(thread), out, rpc_pad_bulk(len), NULL);
UNUSED_NDEBUG(vchiq_status);
vcos_assert(vchiq_status == VCHIQ_SUCCESS);
VCOS_STATUS_T vcos_status = vcos_event_wait(&bulk_event);
UNUSED_NDEBUG(vcos_status);
vcos_assert(vcos_status == VCOS_SUCCESS);
}
}
void rpc_send_bulk(CLIENT_THREAD_STATE_T *thread, const void *in, uint32_t len)
{
if (in && len) {
//CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
merge_flush(thread);
send_bulk(thread, in, len);
}
}
void rpc_send_bulk_gather(CLIENT_THREAD_STATE_T *thread, const void *in, uint32_t len, int32_t stride, uint32_t n)
{
#if 1
if (in && len) {
//CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
merge_flush(thread);
if (len == stride) {
/* hopefully should be the common case */
send_bulk(thread, in, n * len);
} else {
check_workspace(n * len);
rpc_gather(workspace, in, len, stride, n);
send_bulk(thread, workspace, n * len);
}
}
#else
UNREACHABLE();
#endif
}
uint32_t rpc_recv(CLIENT_THREAD_STATE_T *thread, void *out, uint32_t *len_io, RPC_RECV_FLAG_T flags)
{
uint32_t res = 0;
uint32_t len;
bool recv_ctrl;
if (!len_io) { len_io = &len; }
recv_ctrl = flags & (RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN); /* do we want to receive anything in the control channel at all? */
vcos_assert(recv_ctrl || (flags & RPC_RECV_FLAG_BULK)); /* must receive something... */
vcos_assert(!(flags & RPC_RECV_FLAG_CTRL) || !(flags & RPC_RECV_FLAG_BULK)); /* can't receive user data over both bulk and control... */
if (recv_ctrl || len_io[0]) { /* do nothing if we're just receiving bulk of length 0 */
merge_flush(thread);
if (recv_ctrl) {
VCHIQ_HEADER_T *header = vchiu_queue_pop(get_queue(thread));
uint8_t *ctrl = (uint8_t *)header->data;
vcos_assert(header->size >= (!!(flags & RPC_RECV_FLAG_LEN)*4 + !!(flags & RPC_RECV_FLAG_RES)*4) );
if (flags & RPC_RECV_FLAG_LEN) {
len_io[0] = *((uint32_t *)ctrl);
ctrl += 4;
}
if (flags & RPC_RECV_FLAG_RES) {
res = *((uint32_t *)ctrl);
ctrl += 4;
}
if (flags & RPC_RECV_FLAG_CTRL) {
memcpy(out, ctrl, len_io[0]);
ctrl += len_io[0];
}
vcos_assert(ctrl == ((uint8_t *)header->data + header->size));
vchiq_release_message(get_handle(thread), header);
}
if ((flags & RPC_RECV_FLAG_BULK) && len_io[0]) {
if (flags & RPC_RECV_FLAG_BULK_SCATTER) {
if ((len_io[0] == len_io[1]) && !len_io[3] && !len_io[4]) {
/* hopefully should be the common case */
recv_bulk(thread, out, len_io[2] * len_io[0]);
} else {
check_workspace(len_io[2] * len_io[0]);
recv_bulk(thread, workspace, len_io[2] * len_io[0]);
rpc_scatter(out, len_io[0], len_io[1], len_io[2], len_io[3], len_io[4], workspace);
}
} else {
recv_bulk(thread, out, len_io[0]);
}
}
}
return res;
}
void rpc_begin(CLIENT_THREAD_STATE_T *thread)
{
UNUSED(thread);
platform_mutex_acquire(&mutex);
}
void rpc_end(CLIENT_THREAD_STATE_T *thread)
{
UNUSED(thread);
platform_mutex_release(&mutex);
}
void rpc_use(CLIENT_THREAD_STATE_T *thread)
{ // TODO - implement this for linux
UNUSED(thread);
}
void rpc_release(CLIENT_THREAD_STATE_T *thread)
{ // TODO - implement this for linux
UNUSED(thread);
}
void rpc_call8_makecurrent(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t p0,
uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7)
{
if (thread->merge_pos == CLIENT_MAKE_CURRENT_SIZE && *((uint32_t *)thread->merge_buffer) == EGLINTMAKECURRENT_ID)
{
rpc_begin(thread);
vcos_log_trace("rpc_call8_makecurrent collapse onto previous makecurrent");
thread->merge_pos = 0;
RPC_CALL8(eglIntMakeCurrent_impl, thread, EGLINTMAKECURRENT_ID, p0, p1, p2, p3, p4, p5, p6, p7);
vcos_assert(thread->merge_pos == CLIENT_MAKE_CURRENT_SIZE);
rpc_end(thread);
}
else
{
RPC_CALL8(eglIntMakeCurrent_impl, thread, EGLINTMAKECURRENT_ID, p0, p1, p2, p3, p4, p5, p6, p7);
}
}

View File

@@ -0,0 +1,328 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//==============================================================================
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/include/WF/wfc.h"
#include "interface/khronos/wf/wfc_int.h"
//==============================================================================
typedef struct
{
WFCDevice device;
WFCContext context;
WFCElement element;
} WFC_DATA_T;
#define OPENWFC_BOUNCE
//==============================================================================
static EGL_DISPMANX_WINDOW_T *check_default(EGLNativeWindowType win);
//==============================================================================
static bool have_default_dwin;
static EGL_DISPMANX_WINDOW_T default_dwin;
static WFC_DATA_T wfc_data;
//==============================================================================
uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win)
{
EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
return dwin->element; /* same handles used on host and videocore sides */
}
//------------------------------------------------------------------------------
void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
{
EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
*width = dwin->width;
*height = dwin->height;
*swapchain_count = 0;
}
//------------------------------------------------------------------------------
#define NUM_OF_ELEMENTS 2
void *platform_wfc_bounce_thread(void *param)
// Thread function for making previously-created source bounce around the screen.
{
WFC_BOUNCE_DATA_T *bounce_data = (WFC_BOUNCE_DATA_T *) param;
uint32_t i;
int32_t xstep[NUM_OF_ELEMENTS], ystep[NUM_OF_ELEMENTS];
WFCint dest_rect[NUM_OF_ELEMENTS][WFC_RECT_SIZE];
WFCint src_rect[WFC_RECT_SIZE];
WFCElement element_local[NUM_OF_ELEMENTS];
uint32_t num_of_elements = NUM_OF_ELEMENTS;
WFCElement *element = element_local;
// Get context (i.e. screen) dimensions.
int32_t ctx_width;
int32_t ctx_height;
int32_t dest_width, dest_height;
int32_t x, y;
bool use_local_elements = (bounce_data->num_of_elements == 0);
if(!use_local_elements)
{
vcos_assert(bounce_data->num_of_elements <= NUM_OF_ELEMENTS);
vcos_assert(bounce_data->element != NULL);
num_of_elements = bounce_data->num_of_elements;
element = bounce_data->element;
} // if
// Initialise values
ctx_width = wfcGetContextAttribi(bounce_data->device,
bounce_data->context, WFC_CONTEXT_TARGET_WIDTH);
ctx_height = wfcGetContextAttribi(bounce_data->device,
bounce_data->context, WFC_CONTEXT_TARGET_HEIGHT);
// Change background colour
wfcSetContextAttribi(bounce_data->device,
bounce_data->context, WFC_CONTEXT_BG_COLOR, 0x0000FFFF);
float scale = 0.4;
if(num_of_elements == 1)
{scale = 0.75;}
dest_width = bounce_data->dest_width * scale;
dest_height = bounce_data->dest_height * scale;
// Define source rectangle
src_rect[WFC_RECT_X] = bounce_data->src_x;
src_rect[WFC_RECT_Y] = bounce_data->src_y;
src_rect[WFC_RECT_WIDTH] = bounce_data->src_width;
src_rect[WFC_RECT_HEIGHT] = bounce_data->src_height;
for(i = 0; i < num_of_elements; i++)
{
if(use_local_elements)
{
// Create and set up element
element[i] = wfcCreateElement(bounce_data->device,
bounce_data->context, NO_ATTRIBUTES);
vcos_assert(element[i] != WFC_INVALID_HANDLE);
wfcInsertElement(bounce_data->device, element[i], WFC_INVALID_HANDLE);
if(vcos_verify(wfcGetError(bounce_data->device) == WFC_ERROR_NONE)) {};
} // if
else
{
// Element created in calling app, so use that
element[i] = bounce_data->element[i];
} // else
wfcSetElementAttribiv(bounce_data->device, element[i],
WFC_ELEMENT_SOURCE_RECTANGLE, WFC_RECT_SIZE, src_rect);
// Attach existing source
wfcSetElementAttribi(bounce_data->device, element[i],
WFC_ELEMENT_SOURCE, bounce_data->source);
if(num_of_elements > 1)
{
wfcSetElementAttribi(bounce_data->device, element[i],
WFC_ELEMENT_TRANSPARENCY_TYPES, WFC_TRANSPARENCY_ELEMENT_GLOBAL_ALPHA);
wfcSetElementAttribf(bounce_data->device, element[i],
WFC_ELEMENT_GLOBAL_ALPHA, 0.75);
} // if
// Define initial destination rectangle
dest_rect[i][WFC_RECT_X] = i * 100;
dest_rect[i][WFC_RECT_Y] = i * 10;
dest_rect[i][WFC_RECT_WIDTH] = dest_width;
dest_rect[i][WFC_RECT_HEIGHT] = dest_height;
wfcSetElementAttribiv(bounce_data->device, element[i],
WFC_ELEMENT_DESTINATION_RECTANGLE, WFC_RECT_SIZE, dest_rect[i]);
xstep[i] = (i + 1) * 2;
ystep[i] = (i + 1) * 2;
} // for
while(!bounce_data->stop_bouncing)
{
for(i = 0; i < num_of_elements; i++)
{
// Compute new x and y values.
x = dest_rect[i][WFC_RECT_X];
y = dest_rect[i][WFC_RECT_Y];
x += xstep[i];
if(x + dest_width >= ctx_width)
{x = ctx_width - dest_width - 1; xstep[i] *= -1;}
else if(x < 0)
{x = 0; xstep[i] *= -1;}
y += ystep[i];
if(y + dest_height >= ctx_height)
{y = ctx_height - dest_height - 1; ystep[i] *= -1;}
else if(y < 0)
{y = 0; ystep[i] *= -1;}
dest_rect[i][WFC_RECT_X] = x;
dest_rect[i][WFC_RECT_Y] = y;
// Set updated destination rectangle
wfcSetElementAttribiv(bounce_data->device, element[i],
WFC_ELEMENT_DESTINATION_RECTANGLE, WFC_RECT_SIZE, dest_rect[i]);
} // for
wfcCommit(bounce_data->device, bounce_data->context, WFC_TRUE);
vcos_sleep(30);
} // while
// Remove elements
if(use_local_elements)
{
for(i = 0; i < num_of_elements; i++)
{
wfcDestroyElement(bounce_data->device, element[i]);
} // for
} // if
// Change background colour
wfcSetContextAttribi(bounce_data->device,
bounce_data->context, WFC_CONTEXT_BG_COLOR, 0xFF0000FF);
wfcCommit(bounce_data->device, bounce_data->context, WFC_TRUE);
return NULL;
} // platform_bounce_thread
//==============================================================================
static EGL_DISPMANX_WINDOW_T *check_default(EGLNativeWindowType win)
{
// Window already exists, so return it.
if(win != 0)
{return (EGL_DISPMANX_WINDOW_T*) win;}
// Window doesn't exist (= 0), but one has previously been created, so use
// that.
if(have_default_dwin)
{return &default_dwin;}
// Window doesn't exist, and hasn't previously been created, so make it so.
wfc_data.device = wfcCreateDevice(WFC_DEFAULT_DEVICE_ID, NO_ATTRIBUTES);
vcos_assert(wfc_data.device != WFC_INVALID_HANDLE);
wfc_data.context = wfcCreateOnScreenContext(wfc_data.device, 0, NO_ATTRIBUTES);
vcos_assert(wfc_data.context != WFC_INVALID_HANDLE);
WFCint context_width = wfcGetContextAttribi
(wfc_data.device, wfc_data.context, WFC_CONTEXT_TARGET_WIDTH);
WFCint context_height = wfcGetContextAttribi
(wfc_data.device, wfc_data.context, WFC_CONTEXT_TARGET_HEIGHT);
#ifdef OPENWFC_BOUNCE
// Create and attach source
default_dwin.element = 1; // Use arbitrary non-zero value for stream number.
WFCNativeStreamType stream = (WFCNativeStreamType) default_dwin.element;
vcos_assert(stream != WFC_INVALID_HANDLE);
WFCSource source = wfcCreateSourceFromStream(wfc_data.device, wfc_data.context, stream, NO_ATTRIBUTES);
vcos_assert(source != WFC_INVALID_HANDLE);
static VCOS_THREAD_T bounce_thread_data;
static WFC_BOUNCE_DATA_T bounce_data;
bounce_data.device = wfc_data.device;
bounce_data.context = wfc_data.context;
bounce_data.source = source;
bounce_data.src_width = context_width;
bounce_data.src_height = context_height;
bounce_data.dest_width = context_width;
bounce_data.dest_height = context_height;
bounce_data.stop_bouncing = 0;
VCOS_STATUS_T status;
status = vcos_thread_create(&bounce_thread_data, "bounce_thread", NULL,
platform_wfc_bounce_thread, &bounce_data);
vcos_assert(status == VCOS_SUCCESS);
#else
WFCint rect_src[WFC_RECT_SIZE] = { 0, 0, 0, 0 };
WFCint rect_dest[WFC_RECT_SIZE] = { 0, 0, 0, 0 };
wfc_data.element = wfcCreateElement(wfc_data.device, wfc_data.context, NO_ATTRIBUTES);
vcos_assert(wfc_data.element != WFC_INVALID_HANDLE);
default_dwin.element = wfc_data.element;
wfcInsertElement(wfc_data.device, wfc_data.element, WFC_INVALID_HANDLE);
if(vcos_verify(wfcGetError(wfc_data.device) == WFC_ERROR_NONE)) {};
/* Set element attributes */
rect_src[WFC_RECT_X] = 0;
rect_src[WFC_RECT_Y] = 0;
rect_src[WFC_RECT_WIDTH] = context_width;
rect_src[WFC_RECT_HEIGHT] = context_height;
wfcSetElementAttribiv(wfc_data.device, wfc_data.element,
WFC_ELEMENT_SOURCE_RECTANGLE, WFC_RECT_SIZE, rect_src);
rect_dest[WFC_RECT_X] = 0;
rect_dest[WFC_RECT_Y] = 0;
rect_dest[WFC_RECT_WIDTH] = context_width;
rect_dest[WFC_RECT_HEIGHT] = context_height;
wfcSetElementAttribiv(wfc_data.device, wfc_data.element,
WFC_ELEMENT_DESTINATION_RECTANGLE, WFC_RECT_SIZE, rect_dest);
// Create and attach source
default_dwin.element = wfc_data.element; // Stream and element handles given same value.
WFCNativeStreamType stream = (WFCNativeStreamType) default_dwin.element;
vcos_assert(stream != WFC_INVALID_HANDLE);
WFCSource source = wfcCreateSourceFromStream(wfc_data.device, wfc_data.context, stream, NO_ATTRIBUTES);
vcos_assert(source != WFC_INVALID_HANDLE);
wfcSetElementAttribi(wfc_data.device, wfc_data.element, WFC_ELEMENT_SOURCE, source);
#endif
// Send to display
wfcCommit(wfc_data.device, wfc_data.context, WFC_TRUE);
// Enable this and future commits to be enacted immediately
wfcActivate(wfc_data.device, wfc_data.context);
default_dwin.width = 800;
default_dwin.height = 480;
have_default_dwin = true;
return &default_dwin;
} // check_default()
//==============================================================================

View File

@@ -0,0 +1,122 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_PLATFORM_FILLER_VCOS_H
#define KHRN_CLIENT_PLATFORM_FILLER_VCOS_H
#include "interface/vcos/vcos.h"
#include "interface/vcos/vcos_reentrant_mutex.h"
typedef VCOS_STATUS_T KHR_STATUS_T;
#define KHR_SUCCESS VCOS_SUCCESS
#define KHR_EAGAIN VCOS_EAGAIN
/*
mutex
*/
typedef VCOS_REENTRANT_MUTEX_T PLATFORM_MUTEX_T;
/* return !VCOS_SUCCESS on failure */
VCOS_STATIC_INLINE
KHR_STATUS_T platform_mutex_create(PLATFORM_MUTEX_T *mutex) {
return vcos_reentrant_mutex_create(mutex, NULL);
}
VCOS_STATIC_INLINE
void platform_mutex_destroy(PLATFORM_MUTEX_T *mutex) {
vcos_reentrant_mutex_delete(mutex);
}
VCOS_STATIC_INLINE
void platform_mutex_acquire(PLATFORM_MUTEX_T *mutex) {
vcos_reentrant_mutex_lock(mutex);
}
VCOS_STATIC_INLINE
void platform_mutex_release(PLATFORM_MUTEX_T *mutex) {
vcos_reentrant_mutex_unlock(mutex);
}
/*
named counting semaphore
*/
typedef VCOS_NAMED_SEMAPHORE_T PLATFORM_SEMAPHORE_T;
/* return !VCOS_SUCCESS on failure */
extern
KHR_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int name[3], int count);
VCOS_STATIC_INLINE
void khronos_platform_semaphore_destroy(PLATFORM_SEMAPHORE_T *sem) {
vcos_named_semaphore_delete(sem);
}
VCOS_STATIC_INLINE
void khronos_platform_semaphore_acquire(PLATFORM_SEMAPHORE_T *sem) {
vcos_named_semaphore_wait(sem);
}
VCOS_STATIC_INLINE
KHR_STATUS_T khronos_platform_semaphore_try_acquire(PLATFORM_SEMAPHORE_T *sem) {
return vcos_named_semaphore_trywait(sem);
}
VCOS_STATIC_INLINE
void khronos_platform_semaphore_release(PLATFORM_SEMAPHORE_T *sem) {
vcos_named_semaphore_post(sem);
}
/*
thread-local storage
*/
typedef VCOS_TLS_KEY_T PLATFORM_TLS_T;
/* return !VCOS_SUCCCESS on failure */
VCOS_STATIC_INLINE
KHR_STATUS_T platform_tls_create(VCOS_TLS_KEY_T *key) {
return vcos_tls_create(key);
}
#define platform_tls_destroy(tls) vcos_tls_delete(tls)
extern void platform_tls_remove(PLATFORM_TLS_T tls);
/* This has to be per-platform because different platforms do
* thread attachment differently.
*/
extern void *platform_tls_get(PLATFORM_TLS_T tls);
extern void* platform_tls_get_check(PLATFORM_TLS_T tls);
#define platform_tls_set(tls, v) vcos_tls_set(tls, v)
#define platform_tls_remove(tls) vcos_tls_set(tls,NULL)
#endif

View File

@@ -0,0 +1,116 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KHRN_CLIENT_PLATFORM_FILLER_VCOS_VCHIQ_H
#define KHRN_CLIENT_PLATFORM_FILLER_VCOS_VCHIQ_H
#include "interface/vcos/vcos.h"
#include "interface/vcos/vcos_reentrant_mutex.h"
typedef VCOS_STATUS_T KHR_STATUS_T;
#define KHR_SUCCESS VCOS_SUCCESS
/*
mutex
*/
typedef VCOS_REENTRANT_MUTEX_T PLATFORM_MUTEX_T;
/* return !VCOS_SUCCESS on failure */
VCOS_STATIC_INLINE
KHR_STATUS_T platform_mutex_create(PLATFORM_MUTEX_T *mutex) {
return vcos_reentrant_mutex_create(mutex, NULL);
}
VCOS_STATIC_INLINE
void platform_mutex_destroy(PLATFORM_MUTEX_T *mutex) {
vcos_reentrant_mutex_delete(mutex);
}
VCOS_STATIC_INLINE
void platform_mutex_acquire(PLATFORM_MUTEX_T *mutex) {
vcos_reentrant_mutex_lock(mutex);
}
VCOS_STATIC_INLINE
void platform_mutex_release(PLATFORM_MUTEX_T *mutex) {
vcos_reentrant_mutex_unlock(mutex);
}
/*
named counting semaphore
*/
typedef VCOS_NAMED_SEMAPHORE_T PLATFORM_SEMAPHORE_T;
/* return !VCOS_SUCCESS on failure */
extern
KHR_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int name[3], int count);
VCOS_STATIC_INLINE
void khronos_platform_semaphore_destroy(PLATFORM_SEMAPHORE_T *sem) {
vcos_named_semaphore_delete(sem);
}
VCOS_STATIC_INLINE
void khronos_platform_semaphore_acquire(PLATFORM_SEMAPHORE_T *sem) {
vcos_named_semaphore_wait(sem);
}
VCOS_STATIC_INLINE
void khronos_platform_semaphore_release(PLATFORM_SEMAPHORE_T *sem) {
vcos_named_semaphore_post(sem);
}
/*
thread-local storage
*/
typedef VCOS_TLS_KEY_T PLATFORM_TLS_T;
/* return !VCOS_SUCCCESS on failure */
VCOS_STATIC_INLINE
KHR_STATUS_T platform_tls_create(VCOS_TLS_KEY_T *key) {
return vcos_tls_create(key);
}
#define platform_tls_destroy(tls) vcos_tls_delete(tls)
extern void platform_tls_remove(PLATFORM_TLS_T tls);
/* This has to be per-platform because different platforms do
* thread attachment differently.
*/
extern void *platform_tls_get(PLATFORM_TLS_T tls);
#define platform_tls_set(tls, v) vcos_tls_set(tls, v)
#define platform_tls_remove(tls) vcos_tls_set(tls,NULL)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,410 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/egl/egl_client_config.h"
//#define BGR_FB
typedef uint32_t FEATURES_T;
#define FEATURES_PACK(r, g, b, a, d, s, m, mask, lockable) ((FEATURES_T)((((uint32_t)(r)) << 28 | (g) << 24 | (b) << 20 | (a) << 16 | (d) << 8 | (s) << 4 | (m) << 3 | ((mask) >> 3) << 2) | (lockable) << 1))
typedef struct {
FEATURES_T features;
KHRN_IMAGE_FORMAT_T color, depth, multisample, mask;
} FEATURES_AND_FORMATS_T;
/*
formats
For 0 <= id < EGL_MAX_CONFIGS:
formats[id].features is valid
*/
static FEATURES_AND_FORMATS_T formats[EGL_MAX_CONFIGS] = {
// LOCKABLE
// MASK |
// R G B A D S M | | COLOR DEPTH MULTISAMPLE MASK
{FEATURES_PACK(8, 8, 8, 8, 24, 8, 0, 0, 0), ABGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 24, 8, 0, 0, 0), XBGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 8, 24, 0, 0, 0, 0), ABGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 24, 0, 0, 0, 0), XBGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 8, 0, 8, 0, 0, 0), ABGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 0, 8, 0, 0, 0), XBGR_8888, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 8, 0, 0, 0, 0, 0), ABGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 0, 0, 0, 0, 0), XBGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 8, 24, 8, 1, 0, 0), ABGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 24, 8, 1, 0, 0), XBGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 8, 24, 0, 1, 0, 0), ABGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 24, 0, 1, 0, 0), XBGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 8, 0, 8, 1, 0, 0), ABGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 0, 8, 1, 0, 0), XBGR_8888, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 8, 0, 0, 1, 0, 0), ABGR_8888, IMAGE_FORMAT_INVALID, COL_32_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(8, 8, 8, 0, 0, 0, 1, 0, 0), XBGR_8888, IMAGE_FORMAT_INVALID, COL_32_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 24, 8, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 24, 0, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 0, 8, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 0, 0, 0, 0, 0), RGB_565, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 24, 8, 1, 0, 0), RGB_565, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 24, 0, 1, 0, 0), RGB_565, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 0, 8, 1, 0, 0), RGB_565, DEPTH_32_TLBD /*?*/, DEPTH_COL_64_TLBD, IMAGE_FORMAT_INVALID},
{FEATURES_PACK(5, 6, 5, 0, 0, 0, 1, 0, 0), RGB_565, IMAGE_FORMAT_INVALID, COL_32_TLBD, IMAGE_FORMAT_INVALID},
#ifndef EGL_NO_ALPHA_MASK_CONFIGS
{FEATURES_PACK(8, 8, 8, 8, 0, 0, 0, 8, 0), ABGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, A_8_RSO},
{FEATURES_PACK(8, 8, 8, 0, 0, 0, 0, 8, 0), XBGR_8888, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, A_8_RSO},
{FEATURES_PACK(5, 6, 5, 0, 0, 0, 0, 8, 0), RGB_565, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID, A_8_RSO},
#endif
{FEATURES_PACK(5, 6, 5, 0, 16, 0, 0, 0, 0), RGB_565, DEPTH_32_TLBD, IMAGE_FORMAT_INVALID, IMAGE_FORMAT_INVALID},
};
void egl_config_install_configs(int type)
{
uint32_t i;
for (i = 0; i != ARR_COUNT(formats); ++i) {
formats[i].color = (type == 0) ?
khrn_image_to_rso_format(formats[i].color) :
khrn_image_to_tf_format(formats[i].color);
}
}
static bool bindable_rgb(FEATURES_T features);
static bool bindable_rgba(FEATURES_T features);
#include "interface/khronos/egl/egl_client_config_cr.c"
/*
KHRN_IMAGE_FORMAT_T egl_config_get_color_format(int id)
Implementation notes:
We may return an image format which cannot be rendered to.
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
Return value is a hardware framebuffer-supported uncompressed color KHRN_IMAGE_FORMAT_T
*/
KHRN_IMAGE_FORMAT_T egl_config_get_color_format(int id)
{
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
return formats[id].color;
}
/*
KHRN_IMAGE_FORMAT_T egl_config_get_depth_format(int id)
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
Return value is a hardware framebuffer-supported depth KHRN_IMAGE_FORMAT_T or IMAGE_FORMAT_INVALID
*/
KHRN_IMAGE_FORMAT_T egl_config_get_depth_format(int id)
{
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
return formats[id].depth;
}
/*
KHRN_IMAGE_FORMAT_T egl_config_get_mask_format(int id)
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
Return value is a hardware framebuffer-supported mask KHRN_IMAGE_FORMAT_T or IMAGE_FORMAT_INVALID
*/
KHRN_IMAGE_FORMAT_T egl_config_get_mask_format(int id)
{
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
return formats[id].mask;
}
/*
KHRN_IMAGE_FORMAT_T egl_config_get_multisample_format(int id)
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
Return value is a hardware framebuffer-supported multisample color format or IMAGE_FORMAT_INVALID
*/
KHRN_IMAGE_FORMAT_T egl_config_get_multisample_format(int id)
{
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
return formats[id].multisample;
}
/*
bool egl_config_get_multisample(int id)
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
-
*/
bool egl_config_get_multisample(int id)
{
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
return FEATURES_UNPACK_MULTI(formats[id].features);
}
/*
bool bindable_rgb(FEATURES_T features)
bool bindable_rgba(FEATURES_T features)
Preconditions:
features is a valid FEATURES_T
Postconditions:
-
*/
static bool bindable_rgb(FEATURES_T features)
{
return !FEATURES_UNPACK_MULTI(features) && !FEATURES_UNPACK_ALPHA(features);
}
static bool bindable_rgba(FEATURES_T features)
{
return !FEATURES_UNPACK_MULTI(features);
}
bool egl_config_bindable(int id, EGLenum format)
{
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
switch (format) {
case EGL_NO_TEXTURE:
return true;
case EGL_TEXTURE_RGB:
return bindable_rgb(formats[id].features);
case EGL_TEXTURE_RGBA:
return bindable_rgba(formats[id].features);
default:
UNREACHABLE();
return false;
}
}
/*
bool egl_config_match_pixmap_info(int id, KHRN_IMAGE_WRAP_T *image)
TODO: decide how tolerant we should be when matching to native pixmaps.
At present they match if the red, green, blue and alpha channels
all have the same bit depths.
Preconditions:
0 <= id < EGL_MAX_CONFIGS
image is a pointer to a valid KHRN_IMAGE_WRAP_T, possibly with null data pointer
match is a bitmask which is a subset of PLATFORM_PIXMAP_MATCH_NONRENDERABLE|PLATFORM_PIXMAP_MATCH_RENDERABLE
Postconditions:
-
*/
bool egl_config_match_pixmap_info(int id, KHRN_IMAGE_WRAP_T *image)
{
FEATURES_T features = formats[id].features;
KHRN_IMAGE_FORMAT_T format = image->format;
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
return
khrn_image_get_red_size(format) == FEATURES_UNPACK_RED(features) &&
khrn_image_get_green_size(format) == FEATURES_UNPACK_GREEN(features) &&
khrn_image_get_blue_size(format) == FEATURES_UNPACK_BLUE(features) &&
khrn_image_get_alpha_size(format) == FEATURES_UNPACK_ALPHA(features);
}
/*
uint32_t egl_config_get_api_support(int id)
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
Result is a bitmap which is a subset of (EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT)
*/
uint32_t egl_config_get_api_support(int id)
{
/* no configs are api-specific (ie if you can use a config with gl, you can
* use it with vg too, and vice-versa). however, some configs have color
* buffer formats that are incompatible with the hardware, and so can't be
* used with any api. such configs may still be useful eg with the surface
* locking extension... */
#if EGL_KHR_lock_surface
/* to reduce confusion, just say no for all lockable configs. this #if can be
* safely commented out -- the color buffer format check below will catch
* lockable configs we actually can't use */
if (egl_config_is_lockable(id)) {
return 0;
}
#endif
switch (egl_config_get_color_format(id)) {
case ABGR_8888_RSO: case ABGR_8888_TF: case ABGR_8888_LT:
case XBGR_8888_RSO: case XBGR_8888_TF: case XBGR_8888_LT:
case ARGB_8888_RSO: case ARGB_8888_TF: case ARGB_8888_LT:
case XRGB_8888_RSO: case XRGB_8888_TF: case XRGB_8888_LT:
case RGB_565_RSO: case RGB_565_TF: case RGB_565_LT:
#ifndef NO_OPENVG
return (uint32_t)(EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT);
#else
return (uint32_t)(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
#endif
default:
break;
}
return 0;
}
/*
uint32_t egl_config_get_api_conformance(int id)
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
Result is a bitmap which is a subset of (EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT)
*/
uint32_t egl_config_get_api_conformance(int id)
{
/* vg doesn't support multisampled surfaces properly */
return egl_config_get_api_support(id) & ~(FEATURES_UNPACK_MULTI(formats[id].features) ? EGL_OPENVG_BIT : 0);
}
bool egl_config_bpps_match(int id0, int id1) /* bpps of all buffers match */
{
FEATURES_T config0 = formats[id0].features;
FEATURES_T config1 = formats[id1].features;
return
FEATURES_UNPACK_RED(config0) == FEATURES_UNPACK_RED(config1) &&
FEATURES_UNPACK_GREEN(config0) == FEATURES_UNPACK_GREEN(config1) &&
FEATURES_UNPACK_BLUE(config0) == FEATURES_UNPACK_BLUE(config1) &&
FEATURES_UNPACK_ALPHA(config0) == FEATURES_UNPACK_ALPHA(config1) &&
FEATURES_UNPACK_DEPTH(config0) == FEATURES_UNPACK_DEPTH(config1) &&
FEATURES_UNPACK_STENCIL(config0) == FEATURES_UNPACK_STENCIL(config1) &&
FEATURES_UNPACK_MASK(config0) == FEATURES_UNPACK_MASK(config1);
}
#if EGL_KHR_lock_surface
/*
KHRN_IMAGE_FORMAT_T egl_config_get_mapped_format(int id)
Returns the format of the mapped buffer when an EGL surface is locked.
Preconditions:
0 <= id < EGL_MAX_CONFIGS
egl_config_is_lockable(id)
Postconditions:
Return value is RGB_565_RSO or ARGB_8888_RSO
*/
KHRN_IMAGE_FORMAT_T egl_config_get_mapped_format(int id)
{
KHRN_IMAGE_FORMAT_T result;
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
vcos_assert(FEATURES_UNPACK_LOCKABLE(formats[id].features));
/* If any t-format images were lockable, we would convert to raster format here */
result = egl_config_get_color_format(id);
vcos_assert(khrn_image_is_rso(result));
return result;
}
/*
bool egl_config_is_lockable(int id)
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
-
*/
bool egl_config_is_lockable(int id)
{
vcos_assert(id >= 0 && id < EGL_MAX_CONFIGS);
return FEATURES_UNPACK_LOCKABLE(formats[id].features);
}
#endif

View File

@@ -0,0 +1,146 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EGL_CLIENT_CONFIG_H
#define EGL_CLIENT_CONFIG_H
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/common/khrn_int_image.h"
#include "interface/khronos/egl/egl_int_config.h"
#if defined(__BCM2708A0__) || defined(__BCM35230A0__)
#define EGL_NO_ALPHA_MASK_CONFIGS
#endif
#ifdef EGL_NO_ALPHA_MASK_CONFIGS
#define EGL_MAX_CONFIGS 25
#else
#define EGL_MAX_CONFIGS 28
#endif
/*
EGL_CONFIG_MIN_SWAP_INTERVAL
Khronos config attrib name: EGL_MIN_SWAP_INTERVAL
0 <= EGL_CONFIG_MIN_SWAP_INTERVAL <= 1
*/
#define EGL_CONFIG_MIN_SWAP_INTERVAL 0
/*
EGL_CONFIG_MAX_SWAP_INTERVAL
Khronos config attrib name: EGL_MAX_SWAP_INTERVAL
1 <= EGL_CONFIG_MAX_SWAP_INTERVAL
EGL_CONFIG_MIN_SWAP_INTERVAL <= EGL_CONFIG_MAX_SWAP_INTERVAL
*/
#define EGL_CONFIG_MAX_SWAP_INTERVAL 0x7fffffff
/*
EGL_CONFIG_MAX_WIDTH
Khronos config attrib name: EGL_MAX_PBUFFER_WIDTH
EGL_CONFIG_MAX_WIDTH > 0
*/
#define EGL_CONFIG_MAX_WIDTH 2048
/*
EGL_CONFIG_MAX_HEIGHT
Khronos config attrib name: EGL_MAX_PBUFFER_HEIGHT
EGL_CONFIG_MAX_HEIGHT > 0
*/
#define EGL_CONFIG_MAX_HEIGHT 2048
/*
EGLConfig egl_config_from_id(int id)
Converts between our internally-used index and EGLConfig (by adding 1).
Preconditions:
0 <= id < EGL_MAX_CONFIGS
Postconditions:
Return value is a valid EGLConfig
*/
static INLINE EGLConfig egl_config_from_id(int id)
{
return (EGLConfig)(size_t)(id + 1);
}
/*
int egl_config_to_id(EGLConfig config)
Inverse of egl_config_from_id
Preconditions:
config is a valid EGLConfig
Postconditions:
0 <= result < EGL_MAX_CONFIGS
*/
static INLINE int egl_config_to_id(EGLConfig config)
{
return (int)(size_t)config - 1;
}
extern void egl_config_sort(int *ids, bool use_red, bool use_green, bool use_blue, bool use_alpha);
extern bool egl_config_check_attribs(const EGLint *attrib_list, bool *use_red, bool *use_green, bool *use_blue, bool *use_alpha);
extern bool egl_config_filter(int id, const EGLint *attrib_list);
extern bool egl_config_get_attrib(int id, EGLint attrib, EGLint *value);
extern void egl_config_install_configs(int type);
extern KHRN_IMAGE_FORMAT_T egl_config_get_color_format(int id);
extern KHRN_IMAGE_FORMAT_T egl_config_get_depth_format(int id);
extern KHRN_IMAGE_FORMAT_T egl_config_get_mask_format(int id);
extern KHRN_IMAGE_FORMAT_T egl_config_get_multisample_format(int id);
extern bool egl_config_get_multisample(int id);
extern bool egl_config_bindable(int id, EGLenum format);
extern bool egl_config_match_pixmap_info(int id, KHRN_IMAGE_WRAP_T *image);
extern uint32_t egl_config_get_api_support(int id);
extern bool egl_config_bpps_match(int id0, int id1); /* bpps of all buffers match */
extern uint32_t egl_config_get_api_conformance(int id);
#if EGL_KHR_lock_surface
extern KHRN_IMAGE_FORMAT_T egl_config_get_mapped_format(int id);
extern bool egl_config_is_lockable(int id);
#endif
#endif

View File

@@ -0,0 +1,776 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
A FEATURES_T is a structure represented by a bit pattern
Constructed with FEATURES_PACK(red, green, blue, alpha, depth, stencil, multi, mask, lockable)
Attributes are returned with
FEATURES_UNPACK_RED(c)
FEATURES_UNPACK_GREEN(c)
FEATURES_UNPACK_BLUE(c)
FEATURES_UNPACK_ALPHA(c)
FEATURES_UNPACK_DEPTH(c)
FEATURES_UNPACK_STENCIL(c)
FEATURES_UNPACK_MULTI(c)
FEATURES_UNPACK_MASK(c)
FEATURES_UNPACK_LOCKABLE(c)
Additionally,
FEATURES_UNPACK_COLOR(c) = red + green + blue + alpha
Attributes can take the following values:
0 <= red <= 15
0 <= green <= 15
0 <= blue <= 15
0 <= alpha <= 15
0 <= depth <= 255
0 <= stencil <= 15
multi in {0,1}
mask in {0,8}
lockable in {0,1}
*/
#define FEATURES_UNPACK_RED(c) ((EGLint)((c) >> 28 & 0xf))
#define FEATURES_UNPACK_GREEN(c) ((EGLint)((c) >> 24 & 0xf))
#define FEATURES_UNPACK_BLUE(c) ((EGLint)((c) >> 20 & 0xf))
#define FEATURES_UNPACK_ALPHA(c) ((EGLint)((c) >> 16 & 0xf))
#define FEATURES_UNPACK_DEPTH(c) ((EGLint)((c) >> 8 & 0xff))
#define FEATURES_UNPACK_STENCIL(c) ((EGLint)((c) >> 4 & 0xf))
#define FEATURES_UNPACK_MULTI(c) ((EGLint)((c) >> 3 & 0x1))
#define FEATURES_UNPACK_MASK(c) ((EGLint)(((c) >> 2 & 0x1) << 3))
#define FEATURES_UNPACK_LOCKABLE(c) ((c) >> 1 & 0x1)
#define FEATURES_UNPACK_COLOR(c) (FEATURES_UNPACK_RED(c)+FEATURES_UNPACK_GREEN(c)+FEATURES_UNPACK_BLUE(c)+FEATURES_UNPACK_ALPHA(c))
/*
bool egl_config_check_attribs(const EGLint *attrib_list, bool *use_red, bool *use_green, bool *use_blue, bool *use_alpha)
Checks whether all attributes and values are valid. Returns whether the list includes each of
EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, EGL_ALPHA_SIZE
We use the table in eglGetConfigAttrib to guide us as to which values are valid.
Implementation notes:
-
Preconditions:
use_red, use_green, use_blue, use_alpha are valid pointers
attrib_list is NULL or a pointer to an EGL_NONE-terminated list of attribute/value pairs
Postconditions:
If list is valid then we return true and:
use_red is set to true iff attrib_list includes EGL_RED_SIZE and the corresponding value is not 0 or EGL_DONT_CARE
use_green, use_blue, use_alpha similarly
all attributes in list are valid
Else we return false.
Invariants preserved:
-
Invariants used:
-
*/
bool egl_config_check_attribs(const EGLint *attrib_list, bool *use_red, bool *use_green, bool *use_blue, bool *use_alpha)
{
if (!attrib_list)
return true;
while (*attrib_list != EGL_NONE) {
EGLint name = *attrib_list++;
EGLint value = *attrib_list++;
if (name == EGL_RED_SIZE && value != 0 && value != EGL_DONT_CARE)
*use_red = true;
if (name == EGL_GREEN_SIZE && value != 0 && value != EGL_DONT_CARE)
*use_green = true;
if (name == EGL_BLUE_SIZE && value != 0 && value != EGL_DONT_CARE)
*use_blue = true;
if (name == EGL_ALPHA_SIZE && value != 0 && value != EGL_DONT_CARE)
*use_alpha = true;
switch (name) {
case EGL_BUFFER_SIZE:
case EGL_RED_SIZE:
case EGL_GREEN_SIZE:
case EGL_BLUE_SIZE:
case EGL_LUMINANCE_SIZE:
case EGL_ALPHA_SIZE:
case EGL_ALPHA_MASK_SIZE:
if (value != EGL_DONT_CARE && value < 0) return false;
break;
case EGL_BIND_TO_TEXTURE_RGB:
case EGL_BIND_TO_TEXTURE_RGBA:
if (value != EGL_DONT_CARE && value != EGL_FALSE && value != EGL_TRUE)
return false;
break;
case EGL_COLOR_BUFFER_TYPE:
if (value != EGL_DONT_CARE && value != EGL_RGB_BUFFER && value != EGL_LUMINANCE_BUFFER)
return false;
break;
case EGL_CONFIG_CAVEAT:
if (value != EGL_DONT_CARE && value != EGL_NONE && value != EGL_SLOW_CONFIG && value != EGL_NON_CONFORMANT_CONFIG)
return false;
break;
case EGL_CONFIG_ID:
if (value != EGL_DONT_CARE && value < 1)
return false;
break;
case EGL_CONFORMANT:
if (value != EGL_DONT_CARE && (value & ~(EGL_OPENGL_BIT|EGL_OPENGL_ES_BIT|EGL_OPENGL_ES2_BIT|EGL_OPENVG_BIT)))
return false;
break;
case EGL_DEPTH_SIZE:
if (value != EGL_DONT_CARE && value < 0) return false;
break;
case EGL_LEVEL:
break;
case EGL_MATCH_NATIVE_PIXMAP:
/* 1.4 Spec is poor here - says that value has to be a valid handle, but also says that any attribute
* value (other than EGL_LEVEL) can be EGL_DONT_CARE. It also says that the default value is EGL_NONE,
* but that doesn't really make sense - sensible to assume that the default is EGL_DONT_CARE, and don't
* support EGL_NONE as an explicit parameter. (Could theoretically collide with a real handle...)
*/
if (value != EGL_DONT_CARE) {
KHRN_IMAGE_WRAP_T image;
if (!platform_get_pixmap_info((EGLNativePixmapType)(intptr_t)value, &image))
return false;
khrn_platform_release_pixmap_info((EGLNativePixmapType)(intptr_t)value, &image);
}
break;
case EGL_MAX_PBUFFER_WIDTH:
case EGL_MAX_PBUFFER_HEIGHT:
case EGL_MAX_PBUFFER_PIXELS:
break;
case EGL_MAX_SWAP_INTERVAL:
case EGL_MIN_SWAP_INTERVAL:
if (value != EGL_DONT_CARE && value < 0) return false;
break;
case EGL_NATIVE_RENDERABLE:
if (value != EGL_DONT_CARE && value != EGL_FALSE && value != EGL_TRUE)
return false;
break;
case EGL_NATIVE_VISUAL_ID:
case EGL_NATIVE_VISUAL_TYPE:
break;
case EGL_RENDERABLE_TYPE:
if (value != EGL_DONT_CARE && (value & ~(EGL_OPENGL_BIT|EGL_OPENGL_ES_BIT|EGL_OPENGL_ES2_BIT|EGL_OPENVG_BIT)))
return false;
break;
case EGL_SAMPLE_BUFFERS:
case EGL_SAMPLES:
case EGL_STENCIL_SIZE:
if (value != EGL_DONT_CARE && value < 0) return false;
break;
case EGL_SURFACE_TYPE:
{
int valid_bits = EGL_WINDOW_BIT|EGL_PIXMAP_BIT|EGL_PBUFFER_BIT|
EGL_MULTISAMPLE_RESOLVE_BOX_BIT|EGL_SWAP_BEHAVIOR_PRESERVED_BIT|
EGL_VG_COLORSPACE_LINEAR_BIT|EGL_VG_ALPHA_FORMAT_PRE_BIT;
#if EGL_KHR_lock_surface
valid_bits |= EGL_LOCK_SURFACE_BIT_KHR|EGL_OPTIMAL_FORMAT_BIT_KHR;
#endif
if (value != EGL_DONT_CARE && (value & ~valid_bits))
return false;
break;
}
case EGL_TRANSPARENT_TYPE:
if (value != EGL_DONT_CARE && value != EGL_NONE && value != EGL_TRANSPARENT_RGB)
return false;
break;
case EGL_TRANSPARENT_RED_VALUE:
case EGL_TRANSPARENT_GREEN_VALUE:
case EGL_TRANSPARENT_BLUE_VALUE:
if (value != EGL_DONT_CARE && value < 0) return false;
break;
#if EGL_KHR_lock_surface
case EGL_MATCH_FORMAT_KHR:
switch (value) {
case EGL_DONT_CARE:
case EGL_NONE:
case EGL_FORMAT_RGB_565_EXACT_KHR:
case EGL_FORMAT_RGB_565_KHR:
case EGL_FORMAT_RGBA_8888_EXACT_KHR:
case EGL_FORMAT_RGBA_8888_KHR:
break;
default:
return false;
}
break;
#endif
#if EGL_ANDROID_recordable
case EGL_RECORDABLE_ANDROID:
switch (value) {
case EGL_DONT_CARE:
case EGL_TRUE:
case EGL_FALSE:
break;
default:
return false;
}
break;
#endif
default:
return false;
}
}
return true;
}
/*
bool less_than(int id0, int id1, bool use_red, bool use_green, bool use_blue, bool use_alpha)
total ordering on configs; sort in
- decreasing order of color buffer depth, ignoring components for which we have not expressed a preference
- increasing order of color buffer depth
- increasing order of multisample buffers
- increasing order of depth buffer depth
- increasing order of stencil buffer depth
- increasing order of mask buffer depth
Implementation notes:
We ignore:
EGL_CONFIG_CAVEAT (all EGL_NONE)
EGL_COLOR_BUFFER_TYPE (all EGL_RGB_BUFFER)
EGL_SAMPLES (if EGL_SAMPLES is 1 then all 4 else all 0)
EGL_NATIVE_VISUAL_TYPE (all EGL_NONE)
EGL_CONFIG_ID (already sorted in this order and sort algorithm is stable)
Khrnonos documentation:
Sorting of EGLConfigs
If more than one matching EGLConfig is found, then a list of EGLConfigs
is returned. The list is sorted by proceeding in ascending order of the <20>Sort Priority<74>
column of table 3.4. That is, configurations that are not ordered by a lower
numbered rule are sorted by the next higher numbered rule.
Sorting for each rule is either numerically Smaller or Larger as described in the
<20>Sort Order<65> column, or a Special sort order as described for each sort rule below:
1. Special: by EGL CONFIG CAVEAT where the precedence is EGL NONE,
EGL SLOW CONFIG, EGL NON CONFORMANT CONFIG.
2. Special:
by EGL COLOR BUFFER TYPE where the precedence is EGL RGB BUFFER,
EGL LUMINANCE BUFFER.
3. Special: by larger total number of color bits (for an RGB color buffer,
this is the sum of EGL RED SIZE, EGL GREEN SIZE, EGL BLUE SIZE,
and EGL ALPHA SIZE; for a luminance color buffer, the sum of
EGL LUMINANCE SIZE and EGL ALPHA SIZE) [3]. If the requested number
of bits in attrib list for a particular color component is 0 or EGL DONT CARE,
then the number of bits for that component is not considered.
4. Smaller EGL BUFFER SIZE.
5. Smaller EGL SAMPLE BUFFERS.
6. Smaller EGL SAMPLES.
7. Smaller EGL DEPTH SIZE.
8. Smaller EGL STENCIL SIZE.
9. Smaller EGL ALPHA MASK SIZE.
10. Special: by EGL NATIVE VISUAL TYPE (the actual sort order is
implementation-defined, depending on the meaning of native visual types).
11. Smaller EGL CONFIG ID (this is always the last sorting rule, and guarantees
a unique ordering).
EGLConfigs are not sorted with respect to the parameters
EGL BIND TO TEXTURE RGB, EGL BIND TO TEXTURE RGBA, EGL CONFORMANT,
EGL LEVEL, EGL NATIVE RENDERABLE, EGL MAX SWAP INTERVAL,
EGL MIN SWAP INTERVAL, EGL RENDERABLE TYPE, EGL SURFACE TYPE,
EGL TRANSPARENT TYPE, EGL TRANSPARENT RED VALUE,
EGL TRANSPARENT GREEN VALUE, and EGL TRANSPARENT BLUE VALUE.
3This rule places configs with deeper color buffers first in the list returned by eglChooseConfig.
Applications may find this counterintuitive, and need to perform additional processing on the list of
configs to find one best matching their requirements. For example, specifying RGBA depths of 5651
could return a list whose first config has a depth of 8888.
Preconditions:
0 <= id0 < EGL_MAX_CONFIGS
0 <= id1 < EGL_MAX_CONFIGS
Postconditions:
-
Invariants preserved:
-
Invariants used:
-
*/
static bool less_than(int id0, int id1, bool use_red, bool use_green, bool use_blue, bool use_alpha)
{
FEATURES_T features0 = formats[id0].features;
FEATURES_T features1 = formats[id1].features;
EGLint all0 = FEATURES_UNPACK_COLOR(features0);
EGLint all1 = FEATURES_UNPACK_COLOR(features1);
EGLint multi0 = FEATURES_UNPACK_MULTI(features0);
EGLint multi1 = FEATURES_UNPACK_MULTI(features1);
EGLint depth0 = FEATURES_UNPACK_DEPTH(features0);
EGLint depth1 = FEATURES_UNPACK_DEPTH(features1);
EGLint stencil0 = FEATURES_UNPACK_STENCIL(features0);
EGLint stencil1 = FEATURES_UNPACK_STENCIL(features1);
EGLint mask0 = FEATURES_UNPACK_MASK(features0);
EGLint mask1 = FEATURES_UNPACK_MASK(features1);
int used0 = 0;
int used1 = 0;
if (use_red) {
used0 += FEATURES_UNPACK_RED(features0);
used1 += FEATURES_UNPACK_RED(features1);
}
if (use_green) {
used0 += FEATURES_UNPACK_GREEN(features0);
used1 += FEATURES_UNPACK_GREEN(features1);
}
if (use_blue) {
used0 += FEATURES_UNPACK_BLUE(features0);
used1 += FEATURES_UNPACK_BLUE(features1);
}
if (use_alpha) {
used0 += FEATURES_UNPACK_ALPHA(features0);
used1 += FEATURES_UNPACK_ALPHA(features1);
}
return used0 > used1 || (used0 == used1 &&
(all0 < all1 || (all0 == all1 &&
(multi0 < multi1 || (multi0 == multi1 &&
(depth0 < depth1 || (depth0 == depth1 &&
(stencil0 < stencil1 || (stencil0 == stencil1 &&
(mask0 < mask1))))))))));
}
/*
void egl_config_sort(int *ids, EGLBoolean use_red, EGLBoolean use_green, EGLBoolean use_blue, EGLBoolean use_alpha)
Sorts a list of EGL_CONFIG_IDs
Implementation notes:
Uses bubble sort
Preconditions:
ids is a pointer to EGL_MAX_CONFIGS elements
0 <= ids[i] < EGL_MAX_CONFIG for 0 <= i < EGL_MAX_CONFIG
Postconditions:
ids is a permutation of the original
Invariants preserved:
-
Invariants used:
-
*/
void egl_config_sort(int *ids, bool use_red, bool use_green, bool use_blue, bool use_alpha)
{
int i, j;
for (i = 1; i < EGL_MAX_CONFIGS; i++)
for (j = 0; j < EGL_MAX_CONFIGS - i; j++)
if (less_than(ids[j + 1], ids[j], use_red, use_green, use_blue, use_alpha)) {
int temp = ids[j];
ids[j] = ids[j + 1];
ids[j + 1] = temp;
}
}
/*
bool egl_config_get_attrib(int id, EGLint attrib, EGLint *value)
Returns the value of the given attribute of the given config. Returns false
if there is no such attribute.
Implementation notes:
We match EGL_MATCH_NATIVE_PIXMAP here
too, because it *is* a valid attribute according to eglGetConfigAttrib
(even though it doesn't return anything meaningful) and we need it for
egl_config_filter.
Preconditions:
0 <= id < EGL_MAX_CONFIGS
value is a valid pointer
Postconditions:
If attrib is a valid attribute then true is returned and *value is set
Else false is returned
Invariants preserved:
-
Invariants used:
-
*/
bool egl_config_get_attrib(int id, EGLint attrib, EGLint *value)
{
FEATURES_T features = formats[id].features;
switch (attrib) {
case EGL_BUFFER_SIZE:
*value = FEATURES_UNPACK_COLOR(features);
return true;
case EGL_RED_SIZE:
*value = FEATURES_UNPACK_RED(features);
return true;
case EGL_GREEN_SIZE:
*value = FEATURES_UNPACK_GREEN(features);
return true;
case EGL_BLUE_SIZE:
*value = FEATURES_UNPACK_BLUE(features);
return true;
case EGL_LUMINANCE_SIZE:
*value = 0;
return true;
case EGL_ALPHA_SIZE:
*value = FEATURES_UNPACK_ALPHA(features);
return true;
case EGL_ALPHA_MASK_SIZE:
*value = FEATURES_UNPACK_MASK(features);
return true;
case EGL_BIND_TO_TEXTURE_RGB:
*value = bindable_rgb(features);
return true;
case EGL_BIND_TO_TEXTURE_RGBA:
*value = bindable_rgba(features);
return true;
case EGL_COLOR_BUFFER_TYPE:
*value = EGL_RGB_BUFFER;
return true;
case EGL_CONFIG_CAVEAT:
*value = EGL_NONE;
return true;
case EGL_CONFIG_ID:
*value = (EGLint)(uintptr_t)egl_config_from_id(id);
return true;
case EGL_CONFORMANT:
*value = egl_config_get_api_conformance(id);
return true;
case EGL_DEPTH_SIZE:
*value = FEATURES_UNPACK_DEPTH(features);
return true;
case EGL_LEVEL:
*value = 0;
return true;
case EGL_MATCH_NATIVE_PIXMAP:
*value = 0;
return true;
case EGL_MAX_PBUFFER_WIDTH:
*value = EGL_CONFIG_MAX_WIDTH;
return true;
case EGL_MAX_PBUFFER_HEIGHT:
*value = EGL_CONFIG_MAX_HEIGHT;
return true;
case EGL_MAX_PBUFFER_PIXELS:
*value = EGL_CONFIG_MAX_WIDTH * EGL_CONFIG_MAX_HEIGHT;
return true;
case EGL_MAX_SWAP_INTERVAL:
*value = EGL_CONFIG_MAX_SWAP_INTERVAL;
return true;
case EGL_MIN_SWAP_INTERVAL:
*value = EGL_CONFIG_MIN_SWAP_INTERVAL;
return true;
case EGL_NATIVE_RENDERABLE:
*value = EGL_TRUE;
return true;
case EGL_NATIVE_VISUAL_ID:
*value = platform_get_color_format(egl_config_get_color_format(id));
return true;
case EGL_NATIVE_VISUAL_TYPE:
*value = EGL_NONE;
return true;
case EGL_RENDERABLE_TYPE:
*value = egl_config_get_api_support(id);
return true;
case EGL_SAMPLE_BUFFERS:
*value = FEATURES_UNPACK_MULTI(features);
return true;
case EGL_SAMPLES:
*value = FEATURES_UNPACK_MULTI(features) * 4;
return true;
case EGL_STENCIL_SIZE:
*value = FEATURES_UNPACK_STENCIL(features);
return true;
case EGL_SURFACE_TYPE:
*value = (EGLint)(EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT | EGL_VG_COLORSPACE_LINEAR_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT);
#if EGL_KHR_lock_surface
if (egl_config_is_lockable(id))
{
*value |= EGL_LOCK_SURFACE_BIT_KHR;
if (egl_config_get_mapped_format(id) == egl_config_get_color_format(id))
*value |= EGL_OPTIMAL_FORMAT_BIT_KHR; /* Considered optimal if no format conversion needs doing. Currently all lockable surfaces are optimal */
}
#endif
return true;
case EGL_TRANSPARENT_TYPE:
*value = EGL_NONE;
return true;
case EGL_TRANSPARENT_RED_VALUE:
case EGL_TRANSPARENT_GREEN_VALUE:
case EGL_TRANSPARENT_BLUE_VALUE:
*value = 0;
return true;
#if EGL_KHR_lock_surface
case EGL_MATCH_FORMAT_KHR:
if (!egl_config_is_lockable(id))
*value = EGL_NONE;
else {
switch (egl_config_get_mapped_format(id))
{
case RGB_565_RSO:
*value = EGL_FORMAT_RGB_565_EXACT_KHR;
break;
case ARGB_8888_RSO:
*value = EGL_FORMAT_RGBA_8888_EXACT_KHR;
break;
default:
UNREACHABLE();
}
}
return true;
#endif
#if EGL_ANDROID_recordable
case EGL_RECORDABLE_ANDROID:
*value = EGL_TRUE;
return true;
#endif
default:
return false;
}
}
/*
bool egl_config_filter(int id, const EGLint *attrib_list)
Returns whether the given EGL config satisfies the supplied attrib_list.
Implementation notes:
The following attributes:
EGL_COLOR_BUFFER_TYPE
EGL_LEVEL
EGL_RENDERABLE_TYPE
EGL_SURFACE_TYPE
EGL_TRANSPARENT_TYPE
(possibly EGL_MATCH_NATIVE_PIXMAP - see comment)
have default values not equivalent to EGL_DONT_CARE. But all of our configs
match the default value in all of these cases so we can treat the default as
EGL_DONT_CARE for all attributes.
Preconditions:
attrib_list is NULL or a pointer to an EGL_NONE-terminated list of valid attribute/value pairs
0 <= id < EGL_MAX_CONFIGS
Postconditions:
-
Invariants preserved:
-
Invariants used:
-
*/
bool egl_config_filter(int id, const EGLint *attrib_list)
{
if (!attrib_list)
return true;
while (*attrib_list != EGL_NONE) {
EGLint name = *attrib_list++;
EGLint value = *attrib_list++;
EGLint actual_value;
if (!egl_config_get_attrib(id, name, &actual_value) )
{
UNREACHABLE();
return false;
}
switch (name) {
/* Selection Criteria: AtLeast */
case EGL_BUFFER_SIZE:
case EGL_RED_SIZE:
case EGL_GREEN_SIZE:
case EGL_BLUE_SIZE:
case EGL_LUMINANCE_SIZE:
case EGL_ALPHA_SIZE:
case EGL_ALPHA_MASK_SIZE:
case EGL_DEPTH_SIZE:
case EGL_SAMPLE_BUFFERS:
case EGL_SAMPLES:
case EGL_STENCIL_SIZE:
if (value != EGL_DONT_CARE && value > actual_value)
return false;
break;
/* Selection Criteria: Exact */
/*
Excluding EGL_TRANSPARENT_x_VALUE and EGL_MATCH_FORMAT_KHR which are listed in
the table as Exact, but seem to have special rules attached to them.
Excluding EGL_NATIVE_VISUAL_TYPE which is in the ignore list
Excluding EGL_LEVEL because EGL_DONT_CARE is not allowed
*/
case EGL_BIND_TO_TEXTURE_RGB:
case EGL_BIND_TO_TEXTURE_RGBA:
case EGL_COLOR_BUFFER_TYPE:
case EGL_CONFIG_CAVEAT:
case EGL_CONFIG_ID:
case EGL_MAX_SWAP_INTERVAL:
case EGL_MIN_SWAP_INTERVAL:
case EGL_NATIVE_RENDERABLE:
case EGL_TRANSPARENT_TYPE:
#if EGL_ANDROID_recordable
case EGL_RECORDABLE_ANDROID:
#endif
if (value != EGL_DONT_CARE && value != actual_value)
return false;
break;
case EGL_LEVEL:
if (value != actual_value)
return false;
break;
/* Selection Criteria: Mask */
case EGL_CONFORMANT:
case EGL_RENDERABLE_TYPE:
case EGL_SURFACE_TYPE:
if (value != EGL_DONT_CARE && (value & ~actual_value))
return false;
break;
/* Selection Criteria: Special */
case EGL_MATCH_NATIVE_PIXMAP:
if (value != EGL_DONT_CARE) { /* see comments in egl_config_check_attribs */
EGLNativePixmapType pixmap = (EGLNativePixmapType)(intptr_t)value;
KHRN_IMAGE_WRAP_T image;
if (!platform_get_pixmap_info(pixmap, &image)) {
/*
Not actually unreachable in theory!
We should have detected this in egl_config_check_attribs
It's possible that the validity of pixmap has changed since then however...
*/
UNREACHABLE();
return false;
}
if (!egl_config_match_pixmap_info(id, &image) ||
!platform_match_pixmap_api_support(pixmap, egl_config_get_api_support(id)))
{
khrn_platform_release_pixmap_info(pixmap, &image);
return false;
}
khrn_platform_release_pixmap_info(pixmap, &image);
}
break;
#if EGL_KHR_lock_surface
case EGL_MATCH_FORMAT_KHR:
if (!(value == EGL_DONT_CARE || value == actual_value
|| (value == EGL_FORMAT_RGB_565_KHR && actual_value == EGL_FORMAT_RGB_565_EXACT_KHR)
|| (value == EGL_FORMAT_RGBA_8888_KHR && actual_value == EGL_FORMAT_RGBA_8888_EXACT_KHR)))
{
return false;
}
break;
#endif
/* Attributes we can completely ignore */
case EGL_MAX_PBUFFER_WIDTH:
case EGL_MAX_PBUFFER_HEIGHT:
case EGL_MAX_PBUFFER_PIXELS:
case EGL_NATIVE_VISUAL_ID:
/*
"If EGL_MAX_PBUFFER_WIDTH, EGL_MAX_PBUFFER_HEIGHT,
EGL_MAX_PBUFFER_PIXELS, or EGL_NATIVE_VISUAL_ID are specified in
attrib_list, then they are ignored"
*/
case EGL_NATIVE_VISUAL_TYPE:
/*
"if there are no native visual types, then the EGL NATIVE VISUAL TYPE attribute is
ignored."
*/
case EGL_TRANSPARENT_BLUE_VALUE:
case EGL_TRANSPARENT_GREEN_VALUE:
case EGL_TRANSPARENT_RED_VALUE:
/*
"If EGL_TRANSPARENT_TYPE is set to EGL_NONE in attrib_list, then
the EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and
EGL_TRANSPARENT_BLUE_VALUE attributes are ignored."
Possible spec deviation if EGL_TRANSPARENT_TYPE is specified as EGL_DONT_CARE
and EGL_TRANSPARENT_*_VALUE is also specified?
*/
break;
default:
UNREACHABLE();
break;
}
}
return true;
}

View File

@@ -0,0 +1,341 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/vg/vg_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/egl/egl_client_context.h"
#include "interface/khronos/egl/egl_client_surface.h"
#ifdef RPC_DIRECT
#include "interface/khronos/egl/egl_int_impl.h"
#endif
#include <string.h>
#include <stdlib.h>
EGLBoolean egl_context_check_attribs(const EGLint *attrib_list, EGLint max_version, EGLint *version)
{
if (!attrib_list)
return EGL_TRUE;
while (1) {
switch (*attrib_list++) {
case EGL_CONTEXT_CLIENT_VERSION:
{
EGLint value = *attrib_list++;
if (value < 1 || value > max_version)
return EGL_FALSE;
else
*version = value;
break;
}
case EGL_NONE:
return EGL_TRUE;
default:
return EGL_FALSE;
}
}
}
EGL_CONTEXT_T *egl_context_create(EGL_CONTEXT_T *share_context, EGLContext name, EGLDisplay display, EGLConfig configname, EGL_CONTEXT_TYPE_T type)
{
EGL_CONTEXT_T *context = (EGL_CONTEXT_T *)khrn_platform_malloc(sizeof(EGL_CONTEXT_T), "EGL_CONTEXT_T");
if (!context)
return 0;
context->name = name;
context->display = display;
context->configname = configname;
context->type = type;
context->renderbuffer = EGL_NONE;
context->is_current = false;
context->is_destroyed = false;
switch (type) {
#ifndef NO_OPENVG
case OPENVG:
{
VG_CLIENT_SHARED_STATE_T *shared_state;
if (share_context) {
shared_state = ((VG_CLIENT_STATE_T *)share_context->state)->shared_state;
vg_client_shared_state_acquire(shared_state);
} else {
shared_state = vg_client_shared_state_alloc();
if (!shared_state) {
khrn_platform_free(context);
return 0;
}
}
context->state = vg_client_state_alloc(shared_state);
vg_client_shared_state_release(shared_state);
if (!context->state) {
khrn_platform_free(context);
return 0;
}
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
/* uint64_t pid = khronos_platform_get_process_id(); */ /* unused */
context->servercontext = RPC_UINT_RES(RPC_CALL2_RES(eglIntCreateVG_impl,
thread,
EGLINTCREATEVG_ID,
share_context ? share_context->servercontext : 0,
share_context ? share_context->type : OPENVG/*ignored*/));
}
if (!context->servercontext) {
vg_client_state_free((VG_CLIENT_STATE_T *)context->state);
khrn_platform_free(context);
return 0;
}
break;
}
#endif /* NO_OPENVG */
case OPENGL_ES_11:
{
GLXX_CLIENT_STATE_T *state = (GLXX_CLIENT_STATE_T *)khrn_platform_malloc(sizeof(GLXX_CLIENT_STATE_T), "GLXX_CLIENT_STATE_T");
if (!state) {
khrn_platform_free(context);
return 0;
}
context->state = state;
if (gl11_client_state_init(state)) {
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
context->servercontext = RPC_UINT_RES(RPC_CALL2_RES(eglIntCreateGLES11_impl,
thread,
EGLINTCREATEGLES11_ID,
share_context ? share_context->servercontext : 0,
share_context ? share_context->type : OPENGL_ES_11/*ignored*/));
if (!context->servercontext) {
glxx_client_state_free(state);
khrn_platform_free(context);
return 0;
}
}
break;
}
case OPENGL_ES_20:
{
GLXX_CLIENT_STATE_T *state = (GLXX_CLIENT_STATE_T *)khrn_platform_malloc(sizeof(GLXX_CLIENT_STATE_T), "GLXX_CLIENT_STATE_T");
if (!state) {
khrn_platform_free(context);
return 0;
}
context->state = state;
if (gl20_client_state_init(state)) {
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
context->servercontext = RPC_UINT_RES(RPC_CALL2_RES(eglIntCreateGLES20_impl,
thread,
EGLINTCREATEGLES20_ID,
share_context ? share_context->servercontext : 0,
share_context ? share_context->type : OPENGL_ES_20/*ignored*/));
if (!context->servercontext) {
glxx_client_state_free(state);
khrn_platform_free(context);
return 0;
}
}
break;
}
default:
UNREACHABLE();
break;
}
return context;
}
void egl_context_term(EGL_CONTEXT_T *context)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
/* If we're current then there should still be a reference to us */
/* (if this wasn't the case we should call egl_context_release_surfaces here) */
vcos_assert(!context->is_current);
vcos_assert(context->is_destroyed);
switch (context->type) {
#ifndef NO_OPENVG
case OPENVG:
RPC_CALL1(eglIntDestroyVG_impl,
thread,
EGLINTDESTROYVG_ID,
RPC_UINT(context->servercontext));
RPC_FLUSH(thread);
vg_client_state_free((VG_CLIENT_STATE_T *)context->state);
break;
#endif
case OPENGL_ES_11:
case OPENGL_ES_20:
RPC_CALL1(eglIntDestroyGL_impl,
thread,
EGLINTDESTROYGL_ID,
RPC_UINT(context->servercontext));
RPC_FLUSH(thread);
glxx_client_state_free((GLXX_CLIENT_STATE_T *)context->state);
break;
default:
UNREACHABLE();
}
context->state = 0;
}
EGLBoolean egl_context_get_attrib(EGL_CONTEXT_T *context, EGLint attrib, EGLint *value)
{
switch (attrib) {
case EGL_CONFIG_ID:
*value = (int)(intptr_t)context->configname;
return EGL_TRUE;
case EGL_CONTEXT_CLIENT_TYPE:
switch (context->type) {
case OPENGL_ES_11:
case OPENGL_ES_20:
*value = EGL_OPENGL_ES_API;
break;
case OPENVG:
*value = EGL_OPENVG_API;
break;
default:
UNREACHABLE();
break;
}
return EGL_TRUE;
case EGL_CONTEXT_CLIENT_VERSION:
switch (context->type) {
case OPENGL_ES_11:
case OPENVG:
*value = 1;
break;
case OPENGL_ES_20:
*value = 2;
break;
default:
UNREACHABLE();
break;
}
return EGL_TRUE;
case EGL_RENDER_BUFFER:
{
/* TODO: GLES supposedly doesn't support single-buffered rendering. Should we take this into account? */
*value = context->renderbuffer;
return EGL_TRUE;
}
default:
return EGL_FALSE;
}
}
void egl_context_set_callbacks(EGL_CONTEXT_T *context,
void (*gl_render_callback)(void),
void (*gl_flush_callback)(bool),
void (*vg_render_callback)(void),
void (*vg_flush_callback)(bool))
{
switch (context->type) {
case OPENGL_ES_11:
{
GLXX_CLIENT_STATE_T *state = (GLXX_CLIENT_STATE_T *)context->state;
state->render_callback = gl_render_callback;
state->flush_callback = gl_flush_callback;
break;
}
case OPENGL_ES_20:
{
GLXX_CLIENT_STATE_T *state = (GLXX_CLIENT_STATE_T *)context->state;
state->render_callback = gl_render_callback;
state->flush_callback = gl_flush_callback;
break;
}
case OPENVG:
{
VG_CLIENT_STATE_T *state = (VG_CLIENT_STATE_T *)context->state;
state->render_callback = vg_render_callback;
state->flush_callback = vg_flush_callback;
break;
}
default:
UNREACHABLE();
}
}
/*
void egl_context_maybe_free(EGL_CONTEXT_T *context)
Frees a map together with its server-side resources if:
- it has been destroyed
- it is no longer current
Implementation notes:
-
Preconditions:
context is a valid pointer
Postconditions:
Either:
- context->is_destroyed is false (we don't change this), or
- context->is_current is true, or
- context has been deleted.
Invariants preserved:
-
Invariants used:
-
*/
void egl_context_maybe_free(EGL_CONTEXT_T *context)
{
vcos_assert(context);
if (!context->is_destroyed)
return;
if (context->is_current)
return;
egl_context_term(context);
khrn_platform_free(context);
}

View File

@@ -0,0 +1,81 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EGL_CLIENT_CONTEXT_H
#define EGL_CLIENT_CONTEXT_H
#include "interface/khronos/egl/egl_int.h"
typedef struct {
EGLContext name;
EGLDisplay display;
EGLConfig configname;
EGL_CONTEXT_TYPE_T type;
EGLint renderbuffer; //EGL_NONE, EGL_BACK_BUFFER or EGL_SINGLE_BUFFER
void *state; // GLXX_CLIENT_STATE_T or VG_CLIENT_STATE_T
EGL_CONTEXT_ID_T servercontext;
struct CLIENT_THREAD_STATE *thread; // If we are current, which the client state for the thread are we associated with.
/*
is_current
Invariant:
(EGL_CONTEXT_IS_CURRENT)
Iff true, the context is current to some thread.
*/
bool is_current;
/*
is_destroyed
Invariant:
(EGL_CONTEXT_IS_DESTROYED)
Iff true, is not a member of the CLIENT_PROCESS_STATE_T.contexts
*/
bool is_destroyed;
} EGL_CONTEXT_T;
extern EGLBoolean egl_context_check_attribs(const EGLint *attrib_list, EGLint max_version, EGLint *version);
extern EGL_CONTEXT_T *egl_context_create(EGL_CONTEXT_T *share_context, EGLContext name, EGLDisplay display, EGLConfig configname, EGL_CONTEXT_TYPE_T type);
extern void egl_context_term(EGL_CONTEXT_T *context);
extern void egl_context_set_callbacks(EGL_CONTEXT_T *context,
void (*gl_render_callback)(void),
void (*gl_flush_callback)(bool),
void (*vg_render_callback)(void),
void (*vg_flush_callback)(bool));
extern EGLBoolean egl_context_get_attrib(EGL_CONTEXT_T *context, EGLint attrib, EGLint *value);
extern void egl_context_maybe_free(EGL_CONTEXT_T *context);
#endif

View File

@@ -0,0 +1,579 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
EGLAPI EGLint EGLAPIENTRY eglGetError(void)
Khronos documentation:
3.1 Errors
Where possible, when an EGL function fails it has no side effects.
EGL functions usually return an indicator of success or failure; either an
EGLBoolean EGL TRUE or EGL FALSE value, or in the form of an out-of-band
return value indicating failure, such as returning EGL NO CONTEXT instead of a requested
context handle. Additional information about the success or failure of the
most recent EGL function called in a specific thread, in the form of an error code,
can be obtained by calling
EGLint eglGetError();
The error codes that may be returned from eglGetError, and their meanings,
are:
EGL SUCCESS
Function succeeded.
EGL NOT INITIALIZED
EGL is not initialized, or could not be initialized, for the specified display.
EGL BAD ACCESS
EGL cannot access a requested resource (for example, a context is bound in
another thread).
EGL BAD ALLOC
EGL failed to allocate resources for the requested operation.
9
10 CHAPTER 3. EGL FUNCTIONS AND ERRORS
EGL BAD ATTRIBUTE
An unrecognized attribute or attribute value was passed in an attribute list.
EGL BAD CONTEXT
An EGLContext argument does not name a valid EGLContext.
EGL BAD CONFIG
An EGLConfig argument does not name a valid EGLConfig.
EGL BAD CURRENT SURFACE
The current surface of the calling thread is a window, pbuffer, or pixmap that
is no longer valid.
EGL BAD DISPLAY
An EGLDisplay argument does not name a valid EGLDisplay; or, EGL
is not initialized on the specified EGLDisplay.
EGL BAD SURFACE
An EGLSurface argument does not name a valid surface (window, pbuffer,
or pixmap) configured for rendering.
EGL BAD MATCH
Arguments are inconsistent; for example, an otherwise valid context requires
buffers (e.g. depth or stencil) not allocated by an otherwise valid surface.
EGL BAD PARAMETER
One or more argument values are invalid.
EGL BAD NATIVE PIXMAP
An EGLNativePixmapType argument does not refer to a valid native
pixmap.
EGL BAD NATIVE WINDOW
An EGLNativeWindowType argument does not refer to a valid native
window.
EGL CONTEXT LOST
A power management event has occurred. The application must destroy all
contexts and reinitialise client API state and objects to continue rendering,
as described in section 2.6.
When there is no status to return (in other words, when eglGetError is called
as the first EGL call in a thread, or immediately after calling eglReleaseThread),
EGL SUCCESS will be returned.
Implementation notes:
What should we do if eglGetError is called twice? Currently we reset the error to EGL_SUCCESS.
Preconditions:
-
Postconditions:
Result is in the list (CLIENT_THREAD_STATE_ERROR)
Invariants preserved:
-
Invariants used:
(CLIENT_THREAD_STATE_ERROR)
*/
EGLAPI EGLint EGLAPIENTRY eglGetError(void)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_CHECK_THREAD_STATE();
if (thread)
{
EGLint result;
vcos_assert( thread != NULL );
result = thread->error;
thread->error = EGL_SUCCESS;
return result;
}
else
return EGL_SUCCESS;
}
/*
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
Khronos documentation:
3.2 Initialization
Initialization must be performed once for each display prior to calling most other
EGL or client API functions. A display can be obtained by calling
EGLDisplay eglGetDisplay(EGLNativeDisplayType
display id);
The type and format of display id are implementation-specific, and it describes a
specific display provided by the system EGL is running on. For example, an EGL
implementation under X windows would require display id to be an X Display,
while an implementation under Microsoft Windows would require display id to be
a Windows Device Context. If display id is EGL DEFAULT DISPLAY, a default
display is returned.
If no display matching display id is available, EGL NO DISPLAY is returned;
no error condition is raised in this case.
Implementation notes:
We only support one display. This is assumed to have a native display_id
of 0 (==EGL_DEFAULT_DISPLAY) and an EGLDisplay id of 1
Preconditions:
-
Postconditions:
-
Invariants preserved:
-
Invariants used:
-
*/
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_CHECK_THREAD_STATE();
if (thread)
thread->error = EGL_SUCCESS;
return khrn_platform_set_display_id(display_id);
}
//eglInitialize
//eglTerminate
//eglQueryString
/*
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
Khronos documentation:
3.4.1 Querying Configurations
Use
EGLBoolean eglGetConfigs(EGLDisplay dpy,
EGLConfig *configs, EGLint config size,
EGLint *num config);
to get the list of all EGLConfigs that are available on the specified display. configs
is a pointer to a buffer containing config size elements. On success, EGL TRUE is
returned. The number of configurations is returned in num config, and elements 0
through num config - 1 of configs are filled in with the valid EGLConfigs. No
more than config size EGLConfigs will be returned even if more are available on
the specified display. However, if eglGetConfigs is called with configs = NULL,
then no configurations are returned, but the total number of configurations available
will be returned in num config.
On failure, EGL FALSE is returned. An EGL NOT INITIALIZED error is generated
if EGL is not initialized on dpy. An EGL BAD PARAMETER error is generated
if num config is NULL.
Implementation notes:
-
Preconditions:
configs is NULL or a valid pointer to config_size elements
num_config is NULL or a valid pointer
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED EGL is not initialized for the specified display.
EGL_BAD_PARAMETER num_config is null
EGL_SUCCESS Function succeeded.
if more than one condition holds, the first error is generated.
Invariants preserved:
-
Invariants used:
-
*/
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
CLIENT_THREAD_STATE_T *thread;
CLIENT_PROCESS_STATE_T *process;
EGLBoolean result;
if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
{
if (!num_config) {
thread->error = EGL_BAD_PARAMETER;
result = EGL_FALSE;
} else if (!configs) {
thread->error = EGL_SUCCESS;
*num_config = EGL_MAX_CONFIGS;
result = EGL_TRUE;
} else {
int i;
for (i = 0; i < EGL_MAX_CONFIGS && i < config_size; i++)
configs[i] = egl_config_from_id(i);
thread->error = EGL_SUCCESS;
*num_config = i;
result = EGL_TRUE;
}
CLIENT_UNLOCK();
}
else
result = EGL_FALSE;
return result;
}
/*
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
Khronos documentation:
Use
EGLBoolean eglChooseConfig(EGLDisplay dpy, const
EGLint *attrib list, EGLConfig *configs,
EGLint config size, EGLint *num config);
to get EGLConfigs that match a list of attributes. The return value and the meaning
of configs, config size, and num config are the same as for eglGetConfigs.
However, only configurations matching attrib list, as discussed below, will be returned.
On failure, EGL FALSE is returned. An EGL BAD ATTRIBUTE error is generated
if attrib list contains an undefined EGL attribute or an attribute value that is
unrecognized or out of range.
All attribute names in attrib list are immediately followed by the corresponding
desired value. The list is terminated with EGL NONE. If an attribute is not specified
in attrib list, then the default value (listed in Table 3.4) is used (it is said to be
specified implicitly). If EGL DONT CARE is specified as an attribute value, then the
attribute will not be checked. EGL DONT CARE may be specified for all attributes
except EGL LEVEL. If attrib list is NULL or empty (first attribute is EGL NONE),
then selection and sorting of EGLConfigs is done according to the default criteria
in Tables 3.4 and 3.1, as described below under Selection and Sorting.
Selection of EGLConfigs
Attributes are matched in an attribute-specific manner, as shown in the <20>Selection
Critera<EFBFBD> column of table 3.4. The criteria listed in the table have the following
meanings:
AtLeast Only EGLConfigs with an attribute value that meets or exceeds the
specified value are selected.
Exact Only EGLConfigs whose attribute value equals the specified value are
matched.
Mask Only EGLConfigs for which the bits set in the attribute value include all
the bits that are set in the specified value are selected (additional bits might
be set in the attribute value).
Special As described for the specific attribute.
Some of the attributes must match the specified value exactly; others, such as
EGL RED SIZE, must meet or exceed the specified minimum values.
To retrieve an EGLConfig given its unique integer ID, use the
EGL CONFIG ID attribute. When EGL CONFIG ID is specified, all other attributes
are ignored, and only the EGLConfig with the given ID is returned.
If EGL MAX PBUFFER WIDTH, EGL MAX PBUFFER HEIGHT,
EGL MAX PBUFFER PIXELS, or EGL NATIVE VISUAL ID are specified in
attrib list, then they are ignored (however, if present, these attributes must still be
Version 1.3 - December 4, 2006
3.4. CONFIGURATION MANAGEMENT 21
followed by an attribute value in attrib list). If EGL SURFACE TYPE is specified
in attrib list and the mask that follows does not have EGL WINDOW BIT set, or if
there are no native visual types, then the EGL NATIVE VISUAL TYPE attribute is
ignored.
If EGL TRANSPARENT TYPE is set to EGL NONE in attrib list, then
the EGL TRANSPARENT RED VALUE, EGL TRANSPARENT GREEN VALUE, and
EGL TRANSPARENT BLUE VALUE attributes are ignored.
If EGL MATCH NATIVE PIXMAP is specified in attrib list, it must be followed
by an attribute value which is the handle of a valid native pixmap. Only
EGLConfigs which support rendering to that pixmap will match this attribute2.
If no EGLConfig matching the attribute list exists, then the call succeeds, but
num config is set to 0.
Attribute Default Selection Sort Sort
Criteria Order Priority
EGL_BUFFER_SIZE 0 AtLeast Smaller 4
EGL_RED_SIZE 0 AtLeast Special 3
EGL_GREEN_SIZE 0 AtLeast Special 3
EGL_BLUE_SIZE 0 AtLeast Special 3
EGL_LUMINANCE_SIZE 0 AtLeast Special 3
EGL_ALPHA_SIZE 0 AtLeast Special 3
EGL_ALPHA_MASK_SIZE 0 AtLeast Smaller 9
EGL_BIND_TO_TEXTURE_RGB EGL_DONT_CARE Exact None
EGL_BIND_TO_TEXTURE_RGBA EGL_DONT_CARE Exact None
EGL_COLOR_BUFFER_TYPE EGL_RGB BUFFER Exact None 2
EGL_CONFIG_CAVEAT EGL_DONT_CARE Exact Special 1
EGL_CONFIG_ID EGL_DONT_CARE Exact Smaller 11 (last)
EGL_CONFORMANT 0 Mask None
EGL_DEPTH_SIZE 0 AtLeast Smaller 7
EGL_LEVEL 0 Exact None
EGL_MATCH_NATIVE_PIXMAP EGL_NONE Special None
EGL_MAX_SWAP_INTERVAL EGL_DONT_CARE Exact None
EGL_MIN_SWAP_INTERVAL EGL_DONT_CARE Exact None
EGL_NATIVE_RENDERABLE EGL_DONT_CARE Exact None
EGL_NATIVE_VISUAL_TYPE EGL_DONT_CARE Exact Special 10
EGL_RENDERABLE_TYPE EGL_OPENGL_ES_BIT Mask None
EGL_SAMPLE_BUFFERS 0 AtLeast Smaller 5
EGL_SAMPLES 0 AtLeast Smaller 6
EGL_STENCIL_SIZE 0 AtLeast Smaller 8
EGL_SURFACE_TYPE EGL_WINDOW_BIT Mask None
EGL_TRANSPARENT_TYPE EGL_NONE Exact None
EGL_TRANSPARENT_RED_VALUE EGL_DONT_CARE Exact None
EGL_TRANSPARENT_GREEN_VALUE EGL_DONT_CARE Exact None
EGL_TRANSPARENT_BLUE_VALUE EGL_DONT_CARE Exact None
Table 3.4: Default values and match criteria for EGLConfig attributes.
2 The special match criteria for EGL MATCH NATIVE PIXMAP was introduced due to the
difficulty of determining an EGLConfig equivalent to a native pixmap using only color component
depths.
3This rule places configs with deeper color buffers first in the list returned by eglChooseConfig.
Applications may find this counterintuitive, and need to perform additional processing on the list of
configs to find one best matching their requirements. For example, specifying RGBA depths of 5651
could return a list whose first config has a depth of 8888.
Implementation notes:
Configurations are not always returned in the same order; the sort order depends on
whether we care about EGL_RED_SIZE, EGL_GREEN_SIZE, etc. So we need to extract the information
about which of these we care about, then pass this to a sorting function.
Preconditions:
configs is NULL or a valid pointer to config_size elements
num_config is NULL or a valid pointer
attrib_list is NULL or a pointer to an EGL_NONE-terminated list of attribute/value pairs
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED EGL is not initialized for dpy
EGL_BAD_PARAMETER num_config is null
EGL_BAD_ATTRIBUTE attrib_list contains an undefined EGL attribute
EGL_BAD_ATTRIBUTE attrib_list contains an attribute value that is unrecognized or out of range.
EGL_SUCCESS Function succeeded.
if more than one condition holds, the first error is generated.
Invariants preserved:
-
Invariants used:
-
*/
static EGLBoolean choose_config(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config, bool sane)
{
CLIENT_THREAD_STATE_T *thread;
CLIENT_PROCESS_STATE_T *process;
EGLBoolean result;
if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
{
if (!num_config) {
thread->error = EGL_BAD_PARAMETER;
result = EGL_FALSE;
} else {
/*
check for invalid attributes, and find color components for which
we have expressed a preference
*/
bool use_red = false;
bool use_green = false;
bool use_blue = false;
bool use_alpha = false;
if (!egl_config_check_attribs(attrib_list, &use_red, &use_green, &use_blue, &use_alpha)) {
thread->error = EGL_BAD_ATTRIBUTE;
result = EGL_FALSE;
} else {
/*
sort configs
*/
int ids[EGL_MAX_CONFIGS];
int i, j;
for (i = 0; i < EGL_MAX_CONFIGS; i++)
ids[i] = i;
egl_config_sort(ids,
!sane && use_red, !sane && use_green,
!sane && use_blue, !sane && use_alpha);
/*
return configs
*/
j = 0;
for (i = 0; i < EGL_MAX_CONFIGS; i++) {
if (egl_config_filter(ids[i], attrib_list)) {
if (configs && j < config_size) {
configs[j] = egl_config_from_id(ids[i]);
j++;
} else if (!configs) {
// If configs==NULL then we count all configs
// Otherwise we only count the configs we return
j++;
}
}
}
thread->error = EGL_SUCCESS;
*num_config = j;
result = EGL_TRUE;
}
}
CLIENT_UNLOCK();
}
else
result = EGL_FALSE;
return result;
}
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
return choose_config(dpy, attrib_list, configs, config_size, num_config, false);
}
#if EGL_BRCM_sane_choose_config
EGLAPI EGLBoolean EGLAPIENTRY eglSaneChooseConfigBRCM(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
return choose_config(dpy, attrib_list, configs, config_size, num_config, true);
}
#endif
/*
EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
Khronos documentation:
3.4.3 Querying Configuration Attributes
To get the value of an EGLConfig attribute, use
EGLBoolean eglGetConfigAttrib(EGLDisplay dpy,
EGLConfig config, EGLint attribute, EGLint
*value);
If eglGetConfigAttrib succeeds then it returns EGL_TRUE and the value for the
specified attribute is returned in value. Otherwise it returns EGL_FALSE. If attribute
is not a valid attribute then EGL_BAD_ATTRIBUTE is generated.
Refer to Table 3.1 and Table 3.4 for a list of valid EGL attributes.
EGL_BUFFER_SIZE integer depth of the color buffer
EGL_RED_SIZE integer bits of Red in the color buffer
EGL_GREEN_SIZE integer bits of Green in the color buffer
EGL_BLUE_SIZE integer bits of Blue in the color buffer
EGL_LUMINANCE_SIZE integer bits of Luminance in the color buffer
EGL_ALPHA_SIZE integer bits of Alpha in the color buffer
EGL_ALPHA_MASK_SIZE integer bits of Alpha Mask in the mask buffer
EGL_BIND_TO_TEXTURE_RGB boolean True if bindable to RGB textures.
EGL_BIND_TO_TEXTURE_RGBA boolean True if bindable to RGBA textures.
EGL_COLOR_BUFFER_TYPE enum color buffer type
EGL_CONFIG_CAVEAT enum any caveats for the configuration
EGL_CONFIG_ID integer unique EGLConfig identifier
EGL_CONFORMANT bitmask whether contexts created with this config are conformant
EGL_DEPTH_SIZE integer bits of Z in the depth buffer
EGL_LEVEL integer frame buffer level
EGL_MAX_PBUFFER_WIDTH integer maximum width of pbuffer
EGL_MAX_PBUFFER_HEIGHT integer maximum height of pbuffer
EGL_MAX_PBUFFER_PIXELS integer maximum size of pbuffer
EGL_MAX_SWAP_INTERVAL integer maximum swap interval
EGL_MIN_SWAP_INTERVAL integer minimum swap interval
EGL_NATIVE_RENDERABLE boolean EGL_TRUE if native rendering APIs can render to surface
EGL_NATIVE_VISUAL_ID integer handle of corresponding native visual
EGL_NATIVE_VISUAL_TYPE integer native visual type of the associated visual
EGL_RENDERABLE_TYPE bitmask which client APIs are supported
EGL_SAMPLE_BUFFERS integer number of multisample buffers
EGL_SAMPLES integer number of samples per pixel
EGL_STENCIL_SIZE integer bits of Stencil in the stencil buffer
EGL_SURFACE_TYPE bitmask which types of EGL surfaces are supported.
EGL_TRANSPARENT_TYPE enum type of transparency supported
EGL_TRANSPARENT_RED_VALUE integer transparent red value
EGL_TRANSPARENT_GREEN_VALUE integer transparent green value
EGL_TRANSPARENT_BLUE_VALUE integer transparent blue value
Preconditions:
value is null or a valid pointer
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED EGL is not initialized for the specified display.
EGL_BAD_PARAMETER value is null
EGL_BAD_CONFIG config does not name a valid EGLConfig
EGL_BAD_ATTRIBUTE attribute is not a valid attribute
EGL_SUCCESS Function succeeded.
if more than one condition holds, the first error is generated.
*/
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
CLIENT_THREAD_STATE_T *thread;
CLIENT_PROCESS_STATE_T *process;
EGLBoolean result;
if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
{
if (!value) {
thread->error = EGL_BAD_PARAMETER;
result = EGL_FALSE;
} else if (egl_config_to_id(config) < 0 || egl_config_to_id(config) >= EGL_MAX_CONFIGS) {
thread->error = EGL_BAD_CONFIG;
result = EGL_FALSE;
} else if (!egl_config_get_attrib(egl_config_to_id(config), attribute, value)) {
thread->error = EGL_BAD_ATTRIBUTE;
result = EGL_FALSE;
} else {
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
}
CLIENT_UNLOCK();
}
else
result = EGL_FALSE;
return result;
}

View File

@@ -0,0 +1,262 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_client_unmangle.h"
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/GLES/glext.h"
#include "interface/khronos/include/GLES2/gl2.h"
#include "interface/khronos/include/GLES2/gl2ext.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_options.h"
#include "interface/khronos/egl/egl_client_surface.h"
#include "interface/khronos/egl/egl_client_context.h"
#include "interface/khronos/egl/egl_client_config.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/include/VG/vgext.h"
#ifdef RPC_DIRECT
#include "interface/khronos/egl/egl_int_impl.h"
#endif
#if defined(WIN32) || defined(__mips__)
#include "interface/khronos/common/khrn_int_misc_impl.h"
#endif
#ifdef KHRONOS_EGL_PLATFORM_OPENWFC
#include "interface/khronos/wf/wfc_client_stream.h"
#endif
#if defined(RPC_DIRECT_MULTI)
#include "middleware/khronos/egl/egl_server.h"
#endif
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Mangle eglGetProcAddress */
#include "interface/khronos/common/khrn_client_mangle.h"
EGLAPI void EGLAPIENTRY (* eglGetProcAddress(const char *procname))(void)
{
/* Don't mangle the rest */
#include "interface/khronos/common/khrn_client_unmangle.h"
#include "interface/khronos/include/EGL/eglext.h"
/* TODO: any other functions we need to return here? */
if(!procname) return (void(*)(void)) NULL;
#if EGL_KHR_image
if (!strcmp(procname, "eglCreateImageKHR"))
return (void(*)(void))eglCreateImageKHR;
if (!strcmp(procname, "eglDestroyImageKHR"))
return (void(*)(void))eglDestroyImageKHR;
#endif
#ifdef GL_EXT_discard_framebuffer
if (!strcmp(procname, "glDiscardFramebufferEXT"))
return (void(*)(void))glDiscardFramebufferEXT;
#endif
#ifdef GL_EXT_debug_marker
if (!strcmp(procname, "glInsertEventMarkerEXT"))
return (void(*)(void))glInsertEventMarkerEXT;
if (!strcmp(procname, "glPushGroupMarkerEXT"))
return (void(*)(void))glPushGroupMarkerEXT;
if (!strcmp(procname, "glPopGroupMarkerEXT"))
return (void(*)(void))glPopGroupMarkerEXT;
#endif
#if GL_OES_point_size_array
if (!strcmp(procname, "glPointSizePointerOES"))
return (void(*)(void))glPointSizePointerOES;
#endif
#if GL_OES_EGL_image
if (!strcmp(procname, "glEGLImageTargetTexture2DOES"))
return (void(*)(void))glEGLImageTargetTexture2DOES;
if (!strcmp(procname, "glEGLImageTargetRenderbufferStorageOES"))
return (void(*)(void))glEGLImageTargetRenderbufferStorageOES;
#endif
#if GL_OES_matrix_palette
if (!strcmp(procname, "glCurrentPaletteMatrixOES"))
return (void(*)(void))glCurrentPaletteMatrixOES;
if (!strcmp(procname, "glLoadPaletteFromModelViewMatrixOES"))
return (void(*)(void))glLoadPaletteFromModelViewMatrixOES;
if (!strcmp(procname, "glMatrixIndexPointerOES"))
return (void(*)(void))glMatrixIndexPointerOES;
if (!strcmp(procname, "glWeightPointerOES"))
return (void(*)(void))glWeightPointerOES;
#endif
#ifndef NO_OPENVG
#if VG_KHR_EGL_image
if (!strcmp(procname, "vgCreateEGLImageTargetKHR"))
return (void(*)(void))vgCreateEGLImageTargetKHR;
#endif
#endif /* NO_OPENVG */
#if EGL_KHR_lock_surface
if (!strcmp(procname, "eglLockSurfaceKHR"))
return (void(*)(void))eglLockSurfaceKHR;
if (!strcmp(procname, "eglUnlockSurfaceKHR"))
return (void(*)(void))eglUnlockSurfaceKHR;
#endif
#if EGL_KHR_sync
if (!strcmp(procname, "eglCreateSyncKHR"))
return (void(*)(void))eglCreateSyncKHR;
if (!strcmp(procname, "eglDestroySyncKHR"))
return (void(*)(void))eglDestroySyncKHR;
if (!strcmp(procname, "eglClientWaitSyncKHR"))
return (void(*)(void))eglClientWaitSyncKHR;
if (!strcmp(procname, "eglSignalSyncKHR"))
return (void(*)(void))eglSignalSyncKHR;
if (!strcmp(procname, "eglGetSyncAttribKHR"))
return (void(*)(void))eglGetSyncAttribKHR;
#endif
#if EGL_BRCM_perf_monitor
if (!strcmp(procname, "eglInitPerfMonitorBRCM"))
return (void(*)(void))eglInitPerfMonitorBRCM;
if (!strcmp(procname, "eglTermPerfMonitorBRCM"))
return (void(*)(void))eglTermPerfMonitorBRCM;
#endif
#if EGL_BRCM_driver_monitor
if (!strcmp(procname, "eglInitDriverMonitorBRCM"))
return (void(*)(void))eglInitDriverMonitorBRCM;
if (!strcmp(procname, "eglGetDriverMonitorXMLBRCM"))
return (void(*)(void))eglGetDriverMonitorXMLBRCM;
if (!strcmp(procname, "eglTermDriverMonitorBRCM"))
return (void(*)(void))eglTermDriverMonitorBRCM;
#endif
#if EGL_BRCM_perf_stats
if (!strcmp(procname, "eglPerfStatsResetBRCM"))
return (void(*)(void))eglPerfStatsResetBRCM;
if (!strcmp(procname, "eglPerfStatsGetBRCM"))
return (void(*)(void))eglPerfStatsGetBRCM;
#endif
#if EGL_BRCM_mem_usage
if (!strcmp(procname, "eglProcessMemUsageGetBRCM"))
return (void(*)(void))eglProcessMemUsageGetBRCM;
#endif
#ifdef EXPORT_DESTROY_BY_PID
if (!strcmp(procname, "eglDestroyByPidBRCM"))
return (void(*)(void))eglDestroyByPidBRCM;
#endif
#if GL_OES_draw_texture
if (!strcmp(procname, "glDrawTexsOES"))
return (void(*)(void))glDrawTexsOES;
if (!strcmp(procname, "glDrawTexiOES"))
return (void(*)(void))glDrawTexiOES;
if (!strcmp(procname, "glDrawTexxOES"))
return (void(*)(void))glDrawTexxOES;
if (!strcmp(procname, "glDrawTexsvOES"))
return (void(*)(void))glDrawTexsvOES;
if (!strcmp(procname, "glDrawTexivOES"))
return (void(*)(void))glDrawTexivOES;
if (!strcmp(procname, "glDrawTexxvOES"))
return (void(*)(void))glDrawTexxvOES;
if (!strcmp(procname, "glDrawTexfOES"))
return (void(*)(void))glDrawTexfOES;
if (!strcmp(procname, "glDrawTexfvOES"))
return (void(*)(void))glDrawTexfvOES;
#endif
#if GL_OES_query_matrix
if (!strcmp(procname, "glQueryMatrixxOES"))
return (void(*)(void))glQueryMatrixxOES;
#endif
#if GL_OES_framebuffer_object
if (!strcmp(procname, "glIsRenderbufferOES"))
return (void(*)(void))glIsRenderbufferOES;
if (!strcmp(procname, "glBindRenderbufferOES"))
return (void(*)(void))glBindRenderbufferOES;
if (!strcmp(procname, "glDeleteRenderbuffersOES"))
return (void(*)(void))glDeleteRenderbuffersOES;
if (!strcmp(procname, "glGenRenderbuffersOES"))
return (void(*)(void))glGenRenderbuffersOES;
if (!strcmp(procname, "glRenderbufferStorageOES"))
return (void(*)(void))glRenderbufferStorageOES;
if (!strcmp(procname, "glGetRenderbufferParameterivOES"))
return (void(*)(void))glGetRenderbufferParameterivOES;
if (!strcmp(procname, "glIsFramebufferOES"))
return (void(*)(void))glIsFramebufferOES;
if (!strcmp(procname, "glBindFramebufferOES"))
return (void(*)(void))glBindFramebufferOES;
if (!strcmp(procname, "glDeleteFramebuffersOES"))
return (void(*)(void))glDeleteFramebuffersOES;
if (!strcmp(procname, "glGenFramebuffersOES"))
return (void(*)(void))glGenFramebuffersOES;
if (!strcmp(procname, "glCheckFramebufferStatusOES"))
return (void(*)(void))glCheckFramebufferStatusOES;
if (!strcmp(procname, "glFramebufferRenderbufferOES"))
return (void(*)(void))glFramebufferRenderbufferOES;
if (!strcmp(procname, "glFramebufferTexture2DOES"))
return (void(*)(void))glFramebufferTexture2DOES;
if (!strcmp(procname, "glGetFramebufferAttachmentParameterivOES"))
return (void(*)(void))glGetFramebufferAttachmentParameterivOES;
if (!strcmp(procname, "glGenerateMipmapOES"))
return (void(*)(void))glGenerateMipmapOES;
#endif
#if GL_OES_mapbuffer
if (!strcmp(procname, "glGetBufferPointervOES"))
return (void(*)(void))glGetBufferPointervOES;
if (!strcmp(procname, "glMapBufferOES"))
return (void(*)(void))glMapBufferOES;
if (!strcmp(procname, "glUnmapBufferOES"))
return (void(*)(void))glUnmapBufferOES;
#endif
#if EGL_proc_state_valid
if (!strcmp(procname, "eglProcStateValid"))
return (void(*)(void))eglProcStateValid;
#endif
#if EGL_BRCM_flush
if (!strcmp(procname, "eglFlushBRCM"))
return (void(*)(void))eglFlushBRCM;
#endif
#if EGL_BRCM_global_image
if (!strcmp(procname, "eglCreateGlobalImageBRCM"))
return (void(*)(void))eglCreateGlobalImageBRCM;
if (!strcmp(procname, "eglCreateCopyGlobalImageBRCM"))
return (void(*)(void))eglCreateCopyGlobalImageBRCM;
if (!strcmp(procname, "eglDestroyGlobalImageBRCM"))
return (void(*)(void))eglDestroyGlobalImageBRCM;
if (!strcmp(procname, "eglQueryGlobalImageBRCM"))
return (void(*)(void))eglQueryGlobalImageBRCM;
#endif
return (void(*)(void)) NULL;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,918 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define VCOS_LOG_CATEGORY (&egl_client_log_cat)
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/egl/egl_client_surface.h"
#include "interface/khronos/egl/egl_client_config.h"
#include "interface/khronos/common/khrn_client.h"
#ifdef KHRONOS_EGL_PLATFORM_OPENWFC
#include "interface/khronos/wf/wfc_int.h"
#include "interface/khronos/wf/wfc_client_stream.h"
#endif
#ifdef RPC_DIRECT
#include "interface/khronos/egl/egl_int_impl.h"
#endif
#include <stdlib.h>
/*
surface_pool
cache for a small number of pre-allocated surface objects
Validity:
surfaces[i] is valid if allocated & (1<<i)
*/
#define EGL_SURFACE_POOL_SIZE 2
static struct
{
EGL_SURFACE_T surfaces[EGL_SURFACE_POOL_SIZE];
uint32_t allocated;
} surface_pool;
extern VCOS_LOG_CAT_T egl_client_log_cat;
/*
EGL_SURFACE_T* egl_surface_pool_alloc(void)
Implementation notes:
We have a small static pool of structures (surface_pool) which we try and allocate out of
in order to reduce memory fragmentation. When we have run out of space in the pool we
resort to khrn_platform_malloc.
Preconditions:
Whoever calls this must initialise (or free) the returned structure in order to satisfy the invariant
on surface_pool.
Postconditions:
Return value is NULL or an uninitialised EGL_SURFACE_T structure, valid until egl_surface_pool_free
is called.
*/
static EGL_SURFACE_T* egl_surface_pool_alloc(void)
{
int i = 0;
while(surface_pool.allocated & (1 << i))
i++;
if (i < EGL_SURFACE_POOL_SIZE)
{
surface_pool.allocated |= 1 << i;
return &surface_pool.surfaces[i];
}
else
{
return (EGL_SURFACE_T*)khrn_platform_malloc(sizeof(EGL_SURFACE_T), "EGL_SURFACE_T");
}
}
static void egl_surface_pool_free(EGL_SURFACE_T* surface)
{
unsigned int i = 0;
/* todo: this doesn't belong here */
//semaphore now gets destroyed on async callback from VC
if (surface->avail_buffers_valid)
khronos_platform_semaphore_destroy(&surface->avail_buffers);
surface->avail_buffers_valid = false;
i = (unsigned int) (surface - surface_pool.surfaces);
if (i < EGL_SURFACE_POOL_SIZE)
{
surface_pool.allocated &= ~(1 << i);
}
else
{
khrn_platform_free((void*)surface);
}
}
/*
EGLBoolean egl_surface_check_attribs_window(const EGLint *attrib_list, EGLBoolean *linear, EGLBoolean *premult, EGLBoolean *single)
TODO: are we actually supposed to validate our parameters and generate an
error if they're wrong? I can't find an explicit mention in the spec about it.
(except for EGL_WIDTH and EGL_HEIGHT in pbuffer)
Preconditions:
type in {WINDOW, PBUFFER, PIXMAP}
attrib_list is NULL or a pointer to an EGL_NONE-terminated list of attribute/value pairs
linear, premult are NULL or valid pointers
If type == WINDOW then single is NULL or a valid pointer
If type == PBUFFER then width, height, largest_pbuffer, texture_format, texture_target, mipmap_texture are NULL or valid pointers
Postconditions:
-
*/
bool egl_surface_check_attribs(
EGL_SURFACE_TYPE_T type,
const EGLint *attrib_list,
bool *linear,
bool *premult,
bool *single,
int *width,
int *height,
bool *largest_pbuffer,
EGLenum *texture_format,
EGLenum *texture_target,
bool *mipmap_texture
)
{
if (!attrib_list)
return true;
while (*attrib_list != EGL_NONE) {
int name = *attrib_list++;
int value = *attrib_list++;
switch (name) {
case EGL_VG_COLORSPACE:
if (value != EGL_VG_COLORSPACE_sRGB && value != EGL_VG_COLORSPACE_LINEAR)
return false;
if (value == EGL_VG_COLORSPACE_LINEAR && linear != NULL)
*linear = true;
break;
case EGL_VG_ALPHA_FORMAT:
if (value != EGL_VG_ALPHA_FORMAT_NONPRE && value != EGL_VG_ALPHA_FORMAT_PRE)
return false;
if (value == EGL_VG_ALPHA_FORMAT_PRE && premult != NULL)
*premult = true;
break;
/* For WINDOW types only */
case EGL_RENDER_BUFFER:
if (type != WINDOW || (value != EGL_SINGLE_BUFFER && value != EGL_BACK_BUFFER))
return false;
if (value == EGL_SINGLE_BUFFER && single != NULL)
*single = true;
break;
/* For PBUFFER types only */
case EGL_WIDTH:
if (type != PBUFFER || value < 0)
return false;
if (width != NULL)
*width = value;
break;
case EGL_HEIGHT:
if (type != PBUFFER || value < 0)
return false;
if (height != NULL)
*height = value;
break;
case EGL_LARGEST_PBUFFER:
if (type != PBUFFER || (value != EGL_FALSE && value != EGL_TRUE))
return false;
if (largest_pbuffer != NULL)
*largest_pbuffer = value;
break;
case EGL_TEXTURE_FORMAT:
if (type != PBUFFER || (value != EGL_NO_TEXTURE && value != EGL_TEXTURE_RGB && value != EGL_TEXTURE_RGBA))
return false;
if (texture_format != NULL)
*texture_format = value;
break;
case EGL_TEXTURE_TARGET:
if (type != PBUFFER || (value != EGL_NO_TEXTURE && value != EGL_TEXTURE_2D))
return false;
if (texture_target != NULL)
*texture_target = value;
break;
case EGL_MIPMAP_TEXTURE:
if (type != PBUFFER || (value != EGL_FALSE && value != EGL_TRUE))
return false;
if (mipmap_texture != NULL)
*mipmap_texture = value;
break;
default:
return false;
}
}
return true;
}
/*
EGL_SURFACE_T *egl_surface_create(
EGLSurface name,
EGL_SURFACE_TYPE_T type,
EGL_SURFACE_COLORSPACE_T colorspace,
EGL_SURFACE_ALPHAFORMAT_T alphaformat,
uint32_t buffers,
uint32_t width,
uint32_t height,
EGLConfig config,
EGLNativeWindowType win,
uint32_t serverwin,
bool largest_pbuffer,
bool mipmap_texture,
EGLenum texture_format,
EGLenum texture_target,
EGLNativePixmapType pixmap,
const uint32_t *pixmap_server_handle)
Implementation notes:
TODO: respect largest_pbuffer?
Preconditions:
type in {WINDOW,PBUFFER,PIXMAP}
colorspace in {SRGB,LINEAR}
alphaformat in {NONPRE,PRE}
1 <= buffers <= EGL_MAX_BUFFERS
0 < width, 0 < height
If !largest_pbuffer then width <= EGL_CONFIG_MAX_WIDTH, height <= EGL_CONFIG_MAX_HEIGHT
config is a valid EGL config
If type == WINDOW then
win is a valid client-side handle to window W
serverwin is a valid server-side handle to window W
else
win == 0
serverwin == PLATFORM_WIN_NONE
If type == PBBUFFER then
texture_format in {EGL_NO_TEXTURE, EGL_TEXTURE_RGB, EGL_TEXTURE_RGBA}
texture_target in {EGL_NO_TEXTURE, EGL_TEXTURE_2D}
else
largest_pbuffer == mipmap_texture == false
texture_format == texture_target == EGL_NO_TEXTURE
If type == PIXMAP then
pixmap is a valid client-side handle to pixmap P
If pixmap is a server-side pixmap then
pixmap_server_handle is a pointer to two elements, representing a valid server-side handle to pixmap P
else
pixmap_server_handle == 0
else
pixmap == pixmap_server_handle == 0
Postconditions:
Return value is NULL or an EGL_SURFACE_T structure, valid until egl_surface_free is called
Invariants preserved:
All invaraints on EGL_SURFACE_T
*/
EGL_SURFACE_T *egl_surface_create(
EGLSurface name,
EGL_SURFACE_TYPE_T type,
EGL_SURFACE_COLORSPACE_T colorspace,
EGL_SURFACE_ALPHAFORMAT_T alphaformat,
uint32_t buffers,
uint32_t width,
uint32_t height,
EGLConfig config,
EGLNativeWindowType win,
uint32_t serverwin,
bool largest_pbuffer,
bool texture_compatibility,
bool mipmap_texture,
EGLenum texture_format,
EGLenum texture_target,
EGLNativePixmapType pixmap,
const uint32_t *pixmap_server_handle)
{
KHRN_IMAGE_FORMAT_T color;
KHRN_IMAGE_FORMAT_T depth;
KHRN_IMAGE_FORMAT_T mask;
KHRN_IMAGE_FORMAT_T multi;
uint32_t configid;
uint32_t sem_name;
EGLint config_depth_bits;
EGLint config_stencil_bits;
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGL_SURFACE_T *surface = egl_surface_pool_alloc();
vcos_assert(width > 0 && height > 0);
vcos_assert((width <= EGL_CONFIG_MAX_WIDTH && height <= EGL_CONFIG_MAX_HEIGHT) || largest_pbuffer);
if (!surface) {
return 0;
}
/* TODO: respect largest_pbuffer? */
surface->name = name;
surface->type = type;
surface->colorspace = colorspace;
surface->alphaformat = alphaformat;
surface->config = config;
surface->win = win;
surface->width = width;
surface->height = height;
surface->swap_interval = 1;
surface->base_width = width;
surface->base_height = height;
surface->internal_handle = serverwin;
surface->largest_pbuffer = largest_pbuffer;
surface->mipmap_texture = mipmap_texture;
surface->mipmap_level = 0;
surface->texture_format = texture_format;
surface->texture_target = texture_target;
surface->pixmap = pixmap;
surface->pixmap_server_handle[0] = 0;
surface->pixmap_server_handle[1] = (uint32_t)-1;
surface->server_owned = false;
surface->swap_behavior = buffers > 1 ? EGL_BUFFER_DESTROYED : EGL_BUFFER_PRESERVED;
surface->multisample_resolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
surface->context_binding_count = 0;
surface->is_destroyed = false;
#if EGL_KHR_lock_surface
surface->is_locked = false;
surface->mapped_buffer = 0;
#endif
configid = egl_config_to_id(config);
color = egl_config_get_color_format(configid);
if (texture_compatibility) { color = khrn_image_to_tf_format(color); }
if (alphaformat == PRE) { color = (KHRN_IMAGE_FORMAT_T)(color | IMAGE_FORMAT_PRE); }
if (colorspace == LINEAR) { color = (KHRN_IMAGE_FORMAT_T)(color | IMAGE_FORMAT_LIN); }
depth = egl_config_get_depth_format(configid);
mask = egl_config_get_mask_format(configid);
multi = egl_config_get_multisample_format(configid);
/* Find depth and stencil bits from chosen config (these may NOT be the same as the underlying format!) */
egl_config_get_attrib(configid, EGL_DEPTH_SIZE, &config_depth_bits);
egl_config_get_attrib(configid, EGL_STENCIL_SIZE, &config_stencil_bits);
vcos_assert(color != IMAGE_FORMAT_INVALID);
#ifdef KHRONOS_EGL_PLATFORM_OPENWFC
// Create stream for this window
if(type != PBUFFER)
{
WFCNativeStreamType stream = (WFCNativeStreamType) surface->internal_handle;
vcos_assert(stream != WFC_INVALID_HANDLE);
uint32_t failure = wfc_stream_create(stream, WFC_STREAM_FLAGS_EGL);
vcos_log_trace("Creating stream with handle %X", stream);
vcos_assert(failure == 0);
} // if
#endif
surface->buffers = buffers;
if (pixmap_server_handle) {
vcos_assert(type == PIXMAP);
surface->pixmap_server_handle[0] = pixmap_server_handle[0];
surface->pixmap_server_handle[1] = pixmap_server_handle[1];
surface->serverbuffer = RPC_UINT_RES(RPC_CALL7_RES(eglIntCreateWrappedSurface_impl,
thread,
EGLINTCREATEWRAPPEDSURFACE_ID,
RPC_UINT(pixmap_server_handle[0]),
RPC_UINT(pixmap_server_handle[1]),
RPC_UINT(depth),
RPC_UINT(mask),
RPC_UINT(multi),
RPC_UINT(config_depth_bits),
RPC_UINT(config_stencil_bits)));
surface->avail_buffers_valid = false;
} else {
#ifdef __SYMBIAN32__
uint32_t nbuff = 0;
surface->avail_buffers_valid = 0;
if (surface->buffers > 1) {
uint64_t pid = khronos_platform_get_process_id();
int sem[3] = { (int)pid, (int)(pid >> 32), (int)name };
if (khronos_platform_semaphore_create(&surface->avail_buffers, sem, surface->buffers) == KHR_SUCCESS)
surface->avail_buffers_valid = 1;
nbuff = (int)surface->avail_buffers;
}
if (surface->buffers == 1 || surface->avail_buffers_valid) {
uint32_t results[3];
RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
thread,
EGLINTCREATESURFACE_ID,
RPC_UINT(serverwin),
RPC_UINT(buffers),
RPC_UINT(width),
RPC_UINT(height),
RPC_UINT(color),
RPC_UINT(depth),
RPC_UINT(mask),
RPC_UINT(multi),
RPC_UINT(largest_pbuffer),
RPC_UINT(mipmap_texture),
RPC_UINT(config_depth_bits),
RPC_UINT(config_stencil_bits),
RPC_UINT((int)nbuff),
RPC_UINT(type),
results);
#else
surface->avail_buffers_valid = false;
sem_name = KHRN_NO_SEMAPHORE;
#ifndef KHRONOS_EGL_PLATFORM_OPENWFC
if (surface->buffers > 1) {
uint64_t pid = khronos_platform_get_process_id();
int sem[3];
sem[0] = (int)pid; sem[1] = (int)(pid >> 32); sem[2] = (int)name;
sem_name = (int)name;
if (khronos_platform_semaphore_create(&surface->avail_buffers, sem, surface->buffers) == KHR_SUCCESS)
surface->avail_buffers_valid = true;
}
if (sem_name == KHRN_NO_SEMAPHORE || surface->avail_buffers_valid) {
#else
sem_name = (uint32_t)surface->internal_handle;
vcos_log_trace("Surface create has semaphore %X", sem_name);
#endif
uint32_t results[3];
RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
thread,
EGLINTCREATESURFACE_ID,
RPC_UINT(serverwin),
RPC_UINT(buffers),
RPC_UINT(width),
RPC_UINT(height),
RPC_UINT(color),
RPC_UINT(depth),
RPC_UINT(mask),
RPC_UINT(multi),
RPC_UINT(largest_pbuffer),
RPC_UINT(mipmap_texture),
RPC_UINT(config_depth_bits),
RPC_UINT(config_stencil_bits),
RPC_UINT(sem_name),
RPC_UINT(type),
results);
#endif
surface->width = results[0];
surface->height = results[1];
surface->serverbuffer = results[2];
#ifndef KHRONOS_EGL_PLATFORM_OPENWFC
} else {
surface->serverbuffer = 0;
}
#endif
}
if (surface->serverbuffer)
return surface;
else {
/* Server failed to create a surface due to out-of-memory or
we failed to create the named semaphore object. */
egl_surface_pool_free(surface);
return 0;
}
}
#ifndef NO_OPENVG
/* Either returns a valid EGL_SURFACE_T, or returns null and sets error appropriately */
EGL_SURFACE_T *egl_surface_from_vg_image(
VGImage vg_handle,
EGLSurface name,
EGLConfig config,
EGLBoolean largest_pbuffer,
EGLBoolean mipmap_texture,
EGLenum texture_format,
EGLenum texture_target,
EGLint *error)
{
KHRN_IMAGE_FORMAT_T color;
KHRN_IMAGE_FORMAT_T depth;
KHRN_IMAGE_FORMAT_T mask;
KHRN_IMAGE_FORMAT_T multi;
EGLint config_depth_bits;
EGLint config_stencil_bits;
uint32_t results[5];
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGL_SURFACE_T *surface = egl_surface_pool_alloc();
if (!surface) {
*error = EGL_BAD_ALLOC;
return 0;
}
/* TODO: respect largest_pbuffer? */
surface->name = name;
surface->type = PBUFFER;
surface->config = config;
surface->win = 0;
surface->swap_interval = 1;
surface->largest_pbuffer = largest_pbuffer;
surface->mipmap_texture = mipmap_texture;
surface->mipmap_level = 0;
surface->texture_format = texture_format;
surface->texture_target = texture_target;
surface->pixmap = 0;
surface->pixmap_server_handle[0] = 0;
surface->pixmap_server_handle[1] = (uint32_t)-1;
surface->server_owned = false;
surface->context_binding_count = 0;
surface->is_destroyed = false;
#if EGL_KHR_lock_surface
surface->is_locked = false;
surface->mapped_buffer = 0;
#endif
color = egl_config_get_color_format((int)(size_t)config - 1);
depth = egl_config_get_depth_format((int)(size_t)config - 1);
mask = egl_config_get_mask_format((int)(size_t)config - 1);
multi = egl_config_get_multisample_format((int)(size_t)config - 1);
/* Find depth and stencil bits from chosen config (these may NOT be the same as the underlying format!) */
egl_config_get_attrib((int)(size_t)config - 1, EGL_DEPTH_SIZE, &config_depth_bits);
egl_config_get_attrib((int)(size_t)config - 1, EGL_STENCIL_SIZE, &config_stencil_bits);
vcos_assert(color != IMAGE_FORMAT_INVALID);
surface->buffers = 1;
RPC_CALL9_OUT_CTRL(eglIntCreatePbufferFromVGImage_impl,
thread,
EGLINTCREATEPBUFFERFROMVGIMAGE_ID,
RPC_UINT(vg_handle),
RPC_UINT(color),
RPC_UINT(depth),
RPC_UINT(mask),
RPC_UINT(multi),
RPC_UINT(mipmap_texture),
RPC_UINT(config_depth_bits),
RPC_UINT(config_stencil_bits),
results);
surface->avail_buffers_valid = false;
if (results[0]) {
KHRN_IMAGE_FORMAT_T format = (KHRN_IMAGE_FORMAT_T)results[4];
surface->serverbuffer = results[0];
surface->width = results[2];
surface->height = results[3];
/* TODO: picking apart image formats like this seems messy */
surface->colorspace = (format & IMAGE_FORMAT_LIN) ? LINEAR : SRGB;
surface->alphaformat = (format & IMAGE_FORMAT_PRE) ? PRE : NONPRE;
*error = EGL_SUCCESS;
return surface;
} else {
*error = results[1];
egl_surface_pool_free(surface);
return 0;
}
}
#endif /* NO_OPENVG */
/*
void egl_surface_free(EGL_SURFACE_T *surface)
Preconditions:
surface is a valid EGL_SURFACE_T returned from egl_surface_create or egl_surface_from_vg_image
Postconditions:
surface is freed and any associated server-side resources are dereferenced.
*/
void egl_surface_free(EGL_SURFACE_T *surface)
{
CLIENT_THREAD_STATE_T *thread;
vcos_log_trace("egl_surface_free");
thread = CLIENT_GET_THREAD_STATE();
if( surface->type == WINDOW ) {
vcos_log_trace("egl_surface_free: calling platform_destroy_winhandle...");
platform_destroy_winhandle( surface->win, surface->internal_handle );
}
/* return value ignored -- read performed to ensure blocking. we want this to
* block so clients can safely destroy the surface's window as soon as the
* egl call that destroys the surface returns (usually eglDestroySurface, but
* could be eg eglMakeCurrent) */
vcos_log_trace("egl_surface_free: calling eglIntDestroySurface_impl via RPC...; "
"thread = 0x%X; serverbuffer = 0x%X",
(uint32_t) thread, (uint32_t) surface->serverbuffer);
(void)RPC_INT_RES(RPC_CALL1_RES(eglIntDestroySurface_impl,
thread,
EGLINTDESTROYSURFACE_ID,
RPC_UINT(surface->serverbuffer)));
#ifdef KHRONOS_EGL_PLATFORM_OPENWFC
if(surface->internal_handle != PLATFORM_WIN_NONE) // TODO what about pbuffers?
{
vcos_log_trace("egl_surface_free: calling wfc_stream_destroy...");
wfc_stream_destroy((WFCNativeStreamType) surface->internal_handle);
}
#endif
vcos_log_trace("egl_surface_free: calling egl_surface_pool_free...");
egl_surface_pool_free(surface);
vcos_log_trace("egl_surface_free: end");
}
EGLint egl_surface_get_render_buffer(EGL_SURFACE_T *surface)
{
switch (surface->type) {
case WINDOW:
if (surface->buffers == 1)
return EGL_SINGLE_BUFFER;
else
return EGL_BACK_BUFFER;
case PBUFFER:
return EGL_BACK_BUFFER;
case PIXMAP:
return EGL_SINGLE_BUFFER;
default:
UNREACHABLE();
return EGL_NONE;
}
}
EGLBoolean egl_surface_get_attrib(EGL_SURFACE_T *surface, EGLint attrib, EGLint *value)
{
switch (attrib) {
case EGL_VG_ALPHA_FORMAT:
if (surface->alphaformat == NONPRE)
*value = EGL_VG_ALPHA_FORMAT_NONPRE;
else
*value = EGL_VG_ALPHA_FORMAT_PRE;
return EGL_TRUE;
case EGL_VG_COLORSPACE:
if (surface->colorspace == SRGB)
*value = EGL_VG_COLORSPACE_sRGB;
else
*value = EGL_VG_COLORSPACE_LINEAR;
return EGL_TRUE;
case EGL_CONFIG_ID:
*value = (EGLint)(size_t)surface->config;
return EGL_TRUE;
case EGL_HEIGHT:
*value = surface->height;
return EGL_TRUE;
case EGL_HORIZONTAL_RESOLUTION:
case EGL_VERTICAL_RESOLUTION:
*value = EGL_UNKNOWN;
return EGL_TRUE;
case EGL_LARGEST_PBUFFER:
// For a window or pixmap surface, the contents of value are not modified.
if (surface->type == PBUFFER)
*value = surface->largest_pbuffer;
return EGL_TRUE;
case EGL_MIPMAP_TEXTURE:
// Querying EGL_MIPMAP_TEXTURE for a non-pbuffer surface is not
// an error, but value is not modified.
if (surface->type == PBUFFER)
*value = surface->mipmap_texture;
return EGL_TRUE;
case EGL_MIPMAP_LEVEL:
// Querying EGL_MIPMAP_LEVEL for a non-pbuffer surface is not
// an error, but value is not modified.
if (surface->type == PBUFFER)
*value = surface->mipmap_level;
return EGL_TRUE;
case EGL_PIXEL_ASPECT_RATIO:
*value = EGL_DISPLAY_SCALING;
return EGL_TRUE;
case EGL_RENDER_BUFFER:
*value = egl_surface_get_render_buffer(surface);
return EGL_TRUE;
case EGL_SWAP_BEHAVIOR:
*value = surface->swap_behavior;
return EGL_TRUE;
case EGL_MULTISAMPLE_RESOLVE:
*value = surface->multisample_resolve;
return EGL_TRUE;
case EGL_TEXTURE_FORMAT:
// Querying EGL_TEXTURE_FORMAT for a non-pbuffer surface is not
// an error, but value is not modified.
if (surface->type == PBUFFER)
*value = surface->texture_format;
return EGL_TRUE;
case EGL_TEXTURE_TARGET:
// Querying EGL_TEXTURE_TARGET for a non-pbuffer surface is not
// an error, but value is not modified.
if (surface->type == PBUFFER)
*value = surface->texture_target;
return EGL_TRUE;
case EGL_WIDTH:
*value = surface->width;
return EGL_TRUE;
default:
return EGL_FALSE;
}
}
EGLint egl_surface_set_attrib(EGL_SURFACE_T *surface, EGLint attrib, EGLint value)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
switch (attrib) {
case EGL_MIPMAP_LEVEL:
if (surface->type == PBUFFER) {
RPC_CALL2(eglIntSelectMipmap_impl,
thread,
EGLINTSELECTMIPMAP_ID,
RPC_UINT(surface->serverbuffer),
RPC_INT(value));
surface->mipmap_level = value;
}
return EGL_SUCCESS;
case EGL_SWAP_BEHAVIOR:
switch (value) {
case EGL_BUFFER_PRESERVED:
case EGL_BUFFER_DESTROYED:
surface->swap_behavior = value;
return EGL_SUCCESS;
default:
return EGL_BAD_PARAMETER;
}
case EGL_MULTISAMPLE_RESOLVE:
switch (value) {
case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
case EGL_MULTISAMPLE_RESOLVE_BOX:
surface->multisample_resolve = value;
return EGL_SUCCESS;
default:
return EGL_BAD_PARAMETER;
}
default:
return EGL_BAD_ATTRIBUTE;
}
}
#if EGL_KHR_lock_surface
EGLint egl_surface_get_mapped_buffer_attrib(EGL_SURFACE_T *surface, EGLint attrib, EGLint *value)
{
KHRN_IMAGE_FORMAT_T format;
bool is565;
vcos_assert(surface);
if (attrib == EGL_BITMAP_POINTER_KHR || attrib == EGL_BITMAP_PITCH_KHR) {
// Querying either of these causes the buffer to be mapped (if it isn't already)
// They also require that the surface is locked
if (!surface->is_locked) {
return EGL_BAD_ACCESS; // TODO is this the right error?
}
if (!surface->mapped_buffer) {
uint32_t size;
void *buffer;
format = egl_config_get_mapped_format((int)((intptr_t)surface->config - 1)); // type juggling to avoid pointer truncation warnings
size = khrn_image_get_size(format, surface->width, surface->height);
buffer = khrn_platform_malloc(size, "EGL_SURFACE_T.mapped_buffer");
if (!buffer) {
return EGL_BAD_ALLOC;
}
surface->mapped_buffer = buffer;
}
}
if (!egl_config_is_lockable((int)((intptr_t)surface->config-1))) { // type juggling to avoid pointer truncation warnings
// Calling any of these on unlockable surfaces is allowed but returns undefined results
*value = 0;
return EGL_SUCCESS;
}
format = egl_config_get_mapped_format((int)((intptr_t)surface->config-1)); // type juggling to avoid pointer truncation warnings
vcos_assert(format == RGB_565_RSO || format == ARGB_8888_RSO);
is565 = (format == RGB_565_RSO); // else 888
switch (attrib) {
case EGL_BITMAP_POINTER_KHR:
*value = (EGLint)(intptr_t)surface->mapped_buffer; // type juggling to avoid pointer truncation warnings
return EGL_SUCCESS;
case EGL_BITMAP_PITCH_KHR:
*value = khrn_image_get_stride(format, surface->width);
return EGL_SUCCESS;
case EGL_BITMAP_ORIGIN_KHR:
*value = EGL_LOWER_LEFT_KHR; // TODO: is this correct?
return EGL_SUCCESS;
case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
*value = is565 ? 11 : 0; // TODO: I've probably got these wrong too
return EGL_SUCCESS;
case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
*value = is565 ? 5 : 8;
return EGL_SUCCESS;
case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
*value = is565 ? 0 : 16;
return EGL_SUCCESS;
case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
*value = is565 ? 0 : 24;
return EGL_SUCCESS;
case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
*value = 0;
return EGL_SUCCESS;
default:
UNREACHABLE();
return EGL_BAD_PARAMETER;
}
}
#endif
/*
void egl_surface_maybe_free(EGL_SURFACE_T *surface)
Frees a surface together with its server-side resources if:
- it has been destroyed
- it is no longer current
Implementation notes:
-
Preconditions:
surface is a valid pointer
Postconditions:
Either:
- surface->is_destroyed is false (we don't change this), or
- surface->context_binding_count > 0, or
- surface has been deleted.
Invariants preserved:
-
Invariants used:
-
*/
void egl_surface_maybe_free(EGL_SURFACE_T *surface)
{
vcos_assert(surface);
if (!surface->is_destroyed)
return;
if (surface->context_binding_count)
return;
egl_surface_free(surface);
}

View File

@@ -0,0 +1,346 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EGL_CLIENT_SURFACE_H
#define EGL_CLIENT_SURFACE_H
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/include/VG/openvg.h"
#include "interface/khronos/egl/egl_int.h"
#include "interface/khronos/common/khrn_client_platform.h"
typedef enum {
WINDOW,
PBUFFER,
PIXMAP
} EGL_SURFACE_TYPE_T;
typedef enum {
SRGB,
LINEAR
} EGL_SURFACE_COLORSPACE_T;
typedef enum {
NONPRE,
PRE
} EGL_SURFACE_ALPHAFORMAT_T;
typedef struct {
EGLSurface name;
/*
type
Invariants:
(EGL_SURFACE_TYPE)
type in {WINDOW, PBUFFER, PIXMAP}
*/
EGL_SURFACE_TYPE_T type;
/*
colorspace
Invariants:
(EGL_SURFACE_COLORSPACE)
colorspace in {SRGB, LINEAR}
*/
EGL_SURFACE_COLORSPACE_T colorspace;
/*
alphaformat
Invariants:
(EGL_SURFACE_ALPHAFORMAT)
alphaformat in {NONPRE, PRE}
*/
EGL_SURFACE_ALPHAFORMAT_T alphaformat;
/*
config
Invariants:
(EGL_SURFACE_CONFIG)
config is a valid EGLConfig
*/
EGLConfig config;
uint32_t base_width;
uint32_t base_height;
/*
buffers
Usually 1 or 3.
Invariants:
(EGL_SURFACE_BUFFERS)
1 <= buffers <= EGL_MAX_BUFFERS
*/
uint32_t buffers;
/*
width
Invariants:
(EGL_SURFACE_WIDTH)
1 <= width <= EGL_CONFIG_MAX_WIDTH
*/
uint32_t width;
/*
height
Invariants:
(EGL_SURFACE_HEIGHT)
1 <= height <= EGL_CONFIG_MAX_HEIGHT
*/
uint32_t height;
EGL_SURFACE_ID_T serverbuffer;
/*
context_binding_count
Invariant:
(EGL_SURFACE_BINDING_COUNT)
If we are current, how many times we are bound to the current context. Otherwise 0.
*/
uint32_t context_binding_count;
struct CLIENT_THREAD_STATE *thread; // If we are current, which the EGL client state for the thread are we associated with.
#if EGL_KHR_lock_surface
EGLBoolean is_locked;
void *mapped_buffer;
#endif
/*
is_destroyed
Invariant:
(EGL_SURFACE_IS_DESTROYED)
Iff true, is not a member of the CLIENT_PROCESS_STATE_T.surfaces
*/
bool is_destroyed;
/*
swap_behavior
Invariant:
(EGL_SURFACE_SWAP_BEHAVIOUR)
swap_behavior in {EGL_BUFFER_DESTROYED, EGL_BUFFER_PRESERVED}
*/
EGLint swap_behavior;
/*
multisample_resolve
Invariant:
(EGL_SURFACE_MULTISAMPLE_RESOLVE)
multisample_resolve == EGL_MULTISAMPLE_RESOLVE_DEFAULT
*/
EGLint multisample_resolve;
/* For WINDOW types only */
/*
win
Validity:
type == WINDOW
*/
EGLNativeWindowType win;
/*
win
Validity:
type == WINDOW
*/
uint32_t swap_interval;
uint32_t internal_handle; // stores "serverwin"
/*
avail_buffers
named counting semaphore, only used for triple-buffered window surfaces
Validity:
avail_buffers_valid
*/
PLATFORM_SEMAPHORE_T avail_buffers;
bool avail_buffers_valid;
/* For PBUFFER types only */
/*
largest_pbuffer
Validity:
type == PBUFFER
*/
bool largest_pbuffer;
/*
mipmap_texture
Validity:
type == PBUFFER
*/
bool mipmap_texture;
/*
mipmap_level
Validity:
type == PBUFFER
*/
uint32_t mipmap_level;
/*
texture_format
Validity:
type == PBUFFER
Invariant:
texture_format in {EGL_NO_TEXTURE, EGL_TEXTURE_RGB, EGL_TEXTURE_RGBA}
*/
EGLenum texture_format;
/*
texture_target
Validity:
type == PBUFFER
Invariant:
texture_target in {EGL_NO_TEXTURE, EGL_TEXTURE_2D}
*/
EGLenum texture_target;
/* For PIXMAP types only */
/*
pixmap
Validity:
type == PIXMAP
Invariant:
pixmap is a valid client-side pixmap handle for pixmap P
*/
EGLNativePixmapType pixmap;
/*
pixmap_server_handle
Validity:
type == PIXMAP
Invariant:
If P is a server-side pixmap then
pixmap_server_handle is a valid server-side handle for pixmap P
else
pixmap_server_handle = [0, -1]
*/
uint32_t pixmap_server_handle[2];
/*
pixmap_server_handle
Validity:
type == PIXMAP
*/
bool server_owned;
} EGL_SURFACE_T;
extern bool egl_surface_check_attribs(
EGL_SURFACE_TYPE_T type,
const EGLint *attrib_list,
bool *linear,
bool *premult,
bool *single,
int *width,
int *height,
bool *largest_pbuffer,
EGLenum *texture_format,
EGLenum *texture_target,
bool *mipmap_texture
);
struct CLIENT_PROCESS_STATE;
extern EGL_SURFACE_T *egl_surface_create(
EGLSurface name,
EGL_SURFACE_TYPE_T type,
EGL_SURFACE_COLORSPACE_T colorspace,
EGL_SURFACE_ALPHAFORMAT_T alphaformat,
uint32_t buffers,
uint32_t width,
uint32_t height,
EGLConfig config,
EGLNativeWindowType win,
uint32_t serverwin,
bool largest_pbuffer,
bool texture_compatibility,
bool mipmap_texture,
EGLenum texture_format,
EGLenum texture_target,
EGLNativePixmapType pixmap,
const uint32_t *pixmap_server_handle);
extern EGL_SURFACE_T *egl_surface_from_vg_image(
VGImage vg_handle,
EGLSurface name,
EGLConfig config,
EGLBoolean largest_pbuffer,
EGLBoolean mipmap_texture,
EGLenum texture_format,
EGLenum texture_target,
EGLint *error);
extern void egl_surface_free(EGL_SURFACE_T *surface);
extern EGLBoolean egl_surface_get_attrib(EGL_SURFACE_T *surface, EGLint attrib, EGLint *value);
extern EGLint egl_surface_set_attrib(EGL_SURFACE_T *surface, EGLint attrib, EGLint value);
extern EGLint egl_surface_get_render_buffer(EGL_SURFACE_T *surface);
#if EGL_KHR_lock_surface
extern EGLint egl_surface_get_mapped_buffer_attrib(EGL_SURFACE_T *surface, EGLint attrib, EGLint *value);
#endif
extern void egl_surface_maybe_free(EGL_SURFACE_T *surface);
#endif

View File

@@ -0,0 +1,57 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EGL_INT_H
#define EGL_INT_H
typedef enum {
OPENGL_ES_11,
OPENGL_ES_20,
OPENVG
} EGL_CONTEXT_TYPE_T;
// A single colour buffer. Optional ancillary buffers. If triple-buffered,
// three EGL_SERVER_SURFACE_T's share ancillary buffers
typedef uint32_t EGL_SURFACE_ID_T;
// Either a GLES1.1 or GLES2.0 server state
typedef uint32_t EGL_GL_CONTEXT_ID_T;
typedef uint32_t EGL_VG_CONTEXT_ID_T;
typedef uint32_t EGL_CONTEXT_ID_T;
#define EGL_SERVER_NO_SURFACE 0
#define EGL_SERVER_NO_GL_CONTEXT 0
#define EGL_SERVER_NO_VG_CONTEXT 0
#define EGL_SERVER_GL11 1
#define EGL_SERVER_GL20 2
typedef uint32_t EGL_SYNC_ID_T;
#endif

View File

@@ -0,0 +1,34 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EGL_INT_CONFIG_H
#define EGL_INT_CONFIG_H
#define EGL_CONFIG_MAX_WIDTH 2048
#define EGL_CONFIG_MAX_HEIGHT 2048
#endif

View File

@@ -0,0 +1,181 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(KHRN_IMPL_STRUCT)
#define FN(type, name, args) type (*name) args;
#elif defined(KHRN_IMPL_STRUCT_INIT)
#define FN(type, name, args) name,
#else
#define FN(type, name, args) extern type name args;
#endif
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#ifndef KHRN_NO_WFC
#include "interface/khronos/include/WF/wfc.h"
#endif
#include "interface/khronos/include/VG/openvg.h"
#include "interface/khronos/common/khrn_int_image.h"
#include "interface/khronos/egl/egl_int.h"
FN(int, eglIntCreateSurface_impl, (
uint32_t win,
uint32_t buffers,
uint32_t width,
uint32_t height,
KHRN_IMAGE_FORMAT_T colorformat,
KHRN_IMAGE_FORMAT_T depthstencilformat,
KHRN_IMAGE_FORMAT_T maskformat,
KHRN_IMAGE_FORMAT_T multisampleformat,
uint32_t largest,
uint32_t mipmap,
uint32_t config_depth_bits,
uint32_t config_stencil_bits,
uint32_t sem,
uint32_t type,
uint32_t *results))
FN(int, eglIntCreatePbufferFromVGImage_impl, (
VGImage vg_handle,
KHRN_IMAGE_FORMAT_T colorformat,
KHRN_IMAGE_FORMAT_T depthstencilformat,
KHRN_IMAGE_FORMAT_T maskformat,
KHRN_IMAGE_FORMAT_T multisampleformat,
uint32_t mipmap,
uint32_t config_depth_bits,
uint32_t config_stencil_bits,
uint32_t *results))
FN(EGL_SURFACE_ID_T, eglIntCreateWrappedSurface_impl, (
uint32_t handle_0, uint32_t handle_1,
KHRN_IMAGE_FORMAT_T depthstencilformat,
KHRN_IMAGE_FORMAT_T maskformat,
KHRN_IMAGE_FORMAT_T multisample,
uint32_t config_depth_bits,
uint32_t config_stencil_bits))
// Create server states. To actually use these, call, eglIntMakeCurrent.
FN(EGL_GL_CONTEXT_ID_T, eglIntCreateGLES11_impl, (EGL_GL_CONTEXT_ID_T share_id, EGL_CONTEXT_TYPE_T share_type))
FN(EGL_GL_CONTEXT_ID_T, eglIntCreateGLES20_impl, (EGL_GL_CONTEXT_ID_T share, EGL_CONTEXT_TYPE_T share_type))
FN(EGL_VG_CONTEXT_ID_T, eglIntCreateVG_impl, (EGL_VG_CONTEXT_ID_T share, EGL_CONTEXT_TYPE_T share_type))
// Disassociates surface or context objects from their handles. The objects
// themselves still exist as long as there is a reference to them. In
// particular, if you delete part of a triple buffer group, the remaining color
// buffers plus the ancillary buffers all survive.
// If, eglIntDestroySurface is called on a locked surface then that ID is
// guaranteed not to be reused until the surface is unlocked (otherwise a call
// to makevcimage or unlock might target the wrong surface)
FN(int, eglIntDestroySurface_impl, (EGL_SURFACE_ID_T))
FN(void, eglIntDestroyGL_impl, (EGL_GL_CONTEXT_ID_T))
FN(void, eglIntDestroyVG_impl, (EGL_VG_CONTEXT_ID_T))
// Selects the given process id for all operations. Most resource creation is
// associated with the currently selected process id
// Selects the given context, draw and read surfaces for GL operations.
// Selects the given context and surface for VG operations.
// Any of the surfaces may be identical to each other.
// If the GL context or surfaces have changed then GL will be flushed. Similarly for VG.
// If any of the surfaces have been resized then the color and ancillary buffers
// are freed and recreated in the new size.
FN(void, eglIntMakeCurrent_impl, (uint32_t pid_0, uint32_t pid_1, uint32_t glversion, EGL_GL_CONTEXT_ID_T, EGL_SURFACE_ID_T, EGL_SURFACE_ID_T, EGL_VG_CONTEXT_ID_T, EGL_SURFACE_ID_T))
// Flushes one or both context, and waits for the flushes to complete before returning.
// Equivalent to:
// if (flushgl) glFinish())
// if (flushvg) vgFinish())
FN(int, eglIntFlushAndWait_impl, (uint32_t flushgl, uint32_t flushvg))
FN(void, eglIntFlush_impl, (uint32_t flushgl, uint32_t flushvg))
FN(void, eglIntSwapBuffers_impl, (EGL_SURFACE_ID_T s, uint32_t width, uint32_t height, uint32_t handle, uint32_t preserve, uint32_t position))
FN(void, eglIntSelectMipmap_impl, (EGL_SURFACE_ID_T s, int level))
FN(void, eglIntGetColorData_impl, (EGL_SURFACE_ID_T s, KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height, int32_t stride, uint32_t y_offset, void *data))
FN(void, eglIntSetColorData_impl, (EGL_SURFACE_ID_T s, KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height, int32_t stride, uint32_t y_offset, const void *data))
FN(bool, eglIntBindTexImage_impl, (EGL_SURFACE_ID_T s))
FN(void, eglIntReleaseTexImage_impl, (EGL_SURFACE_ID_T s))
FN(void, eglIntSwapInterval_impl, (EGL_SURFACE_ID_T s, uint32_t swap_interval))
FN(void, eglIntGetProcessMemUsage_impl, (uint32_t id_0, uint32_t id_1, uint32_t buffer_len, char *buffer))
FN(void, eglIntGetGlobalMemUsage_impl, (uint32_t *result))
FN(EGL_SYNC_ID_T, eglIntCreateSync_impl, (uint32_t type, uint32_t condition, int32_t threshold, uint32_t sem))
FN(void, eglIntCreateSyncFence_impl, (uint32_t condition, int32_t threshold, uint32_t sem))
FN(void, eglIntDestroySync_impl, (EGL_SYNC_ID_T))
FN(void, eglIntDestroyByPid_impl, (uint32_t pid_0, uint32_t pid_1))
FN(void, eglIntCheckCurrent_impl, (uint32_t pid_0, uint32_t pid_1))
#if EGL_KHR_image
FN(int, eglCreateImageKHR_impl, (uint32_t glversion, EGL_CONTEXT_ID_T ctx, EGLenum target, uint32_t buffer, KHRN_IMAGE_FORMAT_T buffer_format, uint32_t buffer_width, uint32_t buffer_height, uint32_t buffer_stride, EGLint texture_level, EGLint *results))
FN(EGLBoolean, eglDestroyImageKHR_impl, (EGLImageKHR image))
#endif
#if EGL_BRCM_global_image
FN(void, eglCreateGlobalImageBRCM_impl, (EGLint width, EGLint height, EGLint pixel_format, EGLint *id))
FN(void, eglFillGlobalImageBRCM_impl, (EGLint id_0, EGLint id_1, EGLint y, EGLint height, const void *data, EGLint data_stride, EGLint data_pixel_format))
FN(void, eglCreateCopyGlobalImageBRCM_impl, (EGLint src_id_0, EGLint src_id_1, EGLint *id))
FN(bool, eglDestroyGlobalImageBRCM_impl, (EGLint id_0, EGLint id_1))
FN(bool, eglQueryGlobalImageBRCM_impl, (EGLint id_0, EGLint id_1, EGLint *width_height_pixel_format))
#endif
#if EGL_BRCM_perf_monitor
FN(bool, eglInitPerfMonitorBRCM_impl, (void))
FN(void, eglTermPerfMonitorBRCM_impl, (void))
#endif
#if EGL_BRCM_driver_monitor
FN(bool, eglInitDriverMonitorBRCM_impl, (EGLint hw_bank, EGLint l3c_bank))
FN(void, eglTermDriverMonitorBRCM_impl, (void))
FN(void, eglGetDriverMonitorXMLBRCM_impl, (EGLint bufSize, char *xmlStats))
#endif
#if EGL_BRCM_perf_stats
FN(void, eglPerfStatsResetBRCM_impl, ())
FN(void, eglPerfStatsGetBRCM_impl, (EGLint buffer_len, EGLBoolean reset, char *buffer))
#endif
FN(int, eglIntOpenMAXILDoneMarker_impl, (void* component_handle, EGLImageKHR egl_image))
FN(void, eglIntImageSetColorData_impl, (EGLImageKHR image, KHRN_IMAGE_FORMAT_T format,
uint32_t x_offset, uint32_t y_offset,
uint32_t width, uint32_t height, int32_t stride, const void *data))
#ifdef ANDROID
#ifndef KHRN_NO_WFC
FN(void, eglPushRenderingImage_impl, (uint64_t pid, uint32_t window, EGLImageKHR image))
#endif
#endif
#ifdef DIRECT_RENDERING
FN(void, eglDirectRenderingPointer_impl, (EGL_SURFACE_ID_T surface, uint32_t buffer, KHRN_IMAGE_FORMAT_T buffer_format, uint32_t buffer_width, uint32_t buffer_height, uint32_t buffer_stride))
#endif
#undef FN

View File

@@ -0,0 +1,148 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/egl/egl_client_config.h"
#include "interface/khronos/ext/egl_brcm_driver_monitor_client.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#if EGL_BRCM_driver_monitor
EGLAPI EGLBoolean EGLAPIENTRY eglInitDriverMonitorBRCM(EGLDisplay dpy, EGLint hw_bank, EGLint l3c_bank)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process)
{
if (!process->driver_monitor_inited)
process->driver_monitor_inited = RPC_BOOLEAN_RES(RPC_CALL2_RES(eglInitDriverMonitorBRCM_impl,
thread,
EGLINITDRIVERMONITORBRCM_ID,
hw_bank, l3c_bank));
if (process->driver_monitor_inited)
{
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
}
else
{
thread->error = EGL_BAD_ALLOC;
result = EGL_FALSE;
}
}
else
result = EGL_FALSE;
}
CLIENT_UNLOCK();
return result;
}
void egl_driver_monitor_term(CLIENT_PROCESS_STATE_T *process)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (process->driver_monitor_inited)
{
RPC_CALL0(eglTermDriverMonitorBRCM_impl,
thread,
EGLTERMDRIVERMONITORBRCM_ID);
process->driver_monitor_inited = false;
}
}
EGLAPI void EGLAPIENTRY eglGetDriverMonitorXMLBRCM(EGLDisplay dpy, EGLint bufSize, EGLint *length, char *xmlStats)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process)
{
if (process->driver_monitor_inited && xmlStats != NULL)
{
RPC_CALL2_OUT_BULK(eglGetDriverMonitorXMLBRCM_impl,
thread,
EGLGETDRIVERMONITORXMLBRCM_ID, bufSize, xmlStats);
if (length != NULL)
*length = strlen(xmlStats);
}
}
}
CLIENT_UNLOCK();
}
EGLAPI EGLBoolean EGLAPIENTRY eglTermDriverMonitorBRCM(EGLDisplay dpy)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process)
{
egl_driver_monitor_term(process);
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
}
else
result = EGL_FALSE;
}
CLIENT_UNLOCK();
return result;
}
#endif

View File

@@ -0,0 +1,29 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_client.h"
void egl_driver_monitor_term(CLIENT_PROCESS_STATE_T *process);

View File

@@ -0,0 +1,50 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/common/khrn_int_misc_impl.h"
#if EGL_BRCM_flush
/*
any commands issued by the current thread before calling eglFlushBRCM() are
guaranteed to complete before any commands issued by *any* thread after
eglFlushBRCM() returns
*/
EGLAPI void EGLAPIENTRY eglFlushBRCM(void)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
RPC_FLUSH(thread);
}
#endif

View File

@@ -0,0 +1,221 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/egl/egl_client_config.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#if EGL_BRCM_global_image
static EGLint get_bytes_per_pixel(EGLint pixel_format) /* returns 0 for invalid pixel formats */
{
switch (pixel_format & ~EGL_PIXEL_FORMAT_USAGE_MASK_BRCM) {
case EGL_PIXEL_FORMAT_ARGB_8888_PRE_BRCM: return 4;
case EGL_PIXEL_FORMAT_ARGB_8888_BRCM: return 4;
case EGL_PIXEL_FORMAT_XRGB_8888_BRCM: return 4;
case EGL_PIXEL_FORMAT_RGB_565_BRCM: return 2;
case EGL_PIXEL_FORMAT_A_8_BRCM: return 1;
default: return 0; /* invalid */
}
}
/*
failure is indicated by (!id[0] && !id[1]). call eglGetError for the error code
possible failures:
- width/height <= 0 or > EGL_CONFIG_MAX_WIDTH/EGL_CONFIG_MAX_HEIGHT (EGL_BAD_PARAMETER)
- pixel_format invalid (EGL_BAD_PARAMETER)
- insufficient resources (EGL_BAD_ALLOC)
data may be NULL (in which case the image contents are undefined)
*/
EGLAPI void EGLAPIENTRY eglCreateGlobalImageBRCM(EGLint width, EGLint height, EGLint pixel_format, const void *data, EGLint data_stride, EGLint *id)
{
EGLint bytes_per_pixel;
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
/*
check params
*/
bytes_per_pixel = get_bytes_per_pixel(pixel_format);
if ((width <= 0) || (width > EGL_CONFIG_MAX_WIDTH) ||
(height <= 0) || (height > EGL_CONFIG_MAX_HEIGHT) ||
(bytes_per_pixel == 0)) {
thread->error = EGL_BAD_PARAMETER;
id[0] = 0; id[1] = 0;
return;
}
/*
create the image
*/
RPC_CALL4_OUT_CTRL(eglCreateGlobalImageBRCM_impl,
thread,
EGLCREATEGLOBALIMAGEBRCM_ID,
RPC_INT(width),
RPC_INT(height),
RPC_INT(pixel_format),
id);
if (!id[0] && !id[1]) {
thread->error = EGL_BAD_ALLOC;
return;
}
/*
fill the image in if necessary (this can't fail)
*/
if (data) {
#ifdef RPC_DIRECT
RPC_CALL7(eglFillGlobalImageBRCM_impl, thread, no_id, id[0], id[1], 0, height, data, data_stride, pixel_format);
#else
EGLint y = 0;
EGLint chunk_height_max = KHDISPATCH_WORKSPACE_SIZE / (width * bytes_per_pixel);
vcos_assert(chunk_height_max != 0);
while (height != 0) {
VGint chunk_height = _min(height, chunk_height_max);
uint32_t message[] = {
EGLFILLGLOBALIMAGEBRCM_ID,
RPC_INT(id[0]),
RPC_INT(id[1]),
RPC_INT(y),
RPC_INT(chunk_height),
RPC_INT(width * bytes_per_pixel),
RPC_INT(pixel_format) };
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
rpc_begin(thread);
rpc_send_ctrl_begin(thread, sizeof(message));
rpc_send_ctrl_write(thread, message, sizeof(message));
rpc_send_ctrl_end(thread);
rpc_send_bulk_gather(thread, data, width * bytes_per_pixel, data_stride, chunk_height);
data = (const uint8_t *)data + (chunk_height * data_stride);
rpc_end(thread);
height -= chunk_height;
y += chunk_height;
}
#endif
}
}
/*
failure is indicated by (!id[0] && !id[1]). call eglGetError for the error code
possible failures:
- src_id invalid (EGL_BAD_PARAMETER)
- insufficient resources (EGL_BAD_ALLOC)
*/
EGLAPI void EGLAPIENTRY eglCreateCopyGlobalImageBRCM(const EGLint *src_id, EGLint *id)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
/*
create the image
*/
RPC_CALL3_OUT_CTRL(eglCreateCopyGlobalImageBRCM_impl,
thread,
EGLCREATECOPYGLOBALIMAGEBRCM_ID,
RPC_INT(src_id[0]),
RPC_INT(src_id[1]),
id);
if (!id[0] && !id[1]) { /* not enough memory */
thread->error = EGL_BAD_ALLOC;
}
if ((id[0] == -1) && (id[1] == -1)) { /* src_id was invalid */
thread->error = EGL_BAD_PARAMETER;
id[0] = 0; id[1] = 0;
}
}
/*
failure is indicated by returning EGL_FALSE. call eglGetError for the error code
possible failures:
- id invalid (EGL_BAD_PARAMETER)
*/
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyGlobalImageBRCM(const EGLint *id)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
/*
destroy the image
*/
if (!RPC_BOOLEAN_RES(RPC_CALL2_RES(eglDestroyGlobalImageBRCM_impl,
thread,
EGLDESTROYGLOBALIMAGEBRCM_ID,
RPC_INT(id[0]),
RPC_INT(id[1])))) {
thread->error = EGL_BAD_PARAMETER;
return EGL_FALSE;
}
return EGL_TRUE;
}
/*
failure is indicated by returning EGL_FALSE. call eglGetError for the error code
possible failures:
- id invalid (EGL_BAD_PARAMETER)
*/
EGLAPI EGLBoolean EGLAPIENTRY eglQueryGlobalImageBRCM(const EGLint *id, EGLint *width_height_pixel_format)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (!RPC_BOOLEAN_RES(RPC_CALL3_OUT_CTRL_RES(eglQueryGlobalImageBRCM_impl,
thread,
EGLQUERYGLOBALIMAGEBRCM_ID,
RPC_INT(id[0]),
RPC_INT(id[1]),
width_height_pixel_format))) {
thread->error = EGL_BAD_PARAMETER;
return EGL_FALSE;
}
return EGL_TRUE;
}
#endif

View File

@@ -0,0 +1,149 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/egl/egl_client_config.h"
#include "interface/khronos/ext/egl_brcm_perf_monitor_client.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#if EGL_BRCM_perf_monitor
EGLAPI EGLBoolean EGLAPIENTRY eglInitPerfMonitorBRCM(EGLDisplay dpy)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process) {
if (!process->perf_monitor_inited)
process->perf_monitor_inited = RPC_BOOLEAN_RES(RPC_CALL0_RES(eglInitPerfMonitorBRCM_impl,
EGLINITPERFMONITORBRCM_ID));
if (process->perf_monitor_inited) {
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
} else {
thread->error = EGL_BAD_ALLOC;
result = EGL_FALSE;
}
} else
result = EGL_FALSE;
}
CLIENT_UNLOCK();
return result;
}
void egl_perf_monitor_term(CLIENT_PROCESS_STATE_T *process)
{
if (process->perf_monitor_inited) {
RPC_CALL0(eglTermPerfMonitorBRCM_impl,
EGLTERMPERFMONITORBRCM_ID);
process->perf_monitor_inited = false;
}
}
EGLAPI EGLBoolean EGLAPIENTRY eglTermPerfMonitorBRCM(EGLDisplay dpy)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process) {
egl_perf_monitor_term(process);
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
} else
result = EGL_FALSE;
}
CLIENT_UNLOCK();
return result;
}
#endif
#if EGL_BRCM_perf_stats
EGLAPI void eglPerfStatsResetBRCM(void)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
RPC_CALL0(eglPerfStatsResetBRCM_impl, thread, EGLPERFSTATSRESETBRCM_ID);
}
EGLAPI void eglPerfStatsGetBRCM(char *buffer, EGLint buffer_len, EGLBoolean reset)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
// int len = _min(_max(buffer_len, 0), KHDISPATCH_WORKSPACE_SIZE);
RPC_CALL3_OUT_BULK(eglPerfStatsGetBRCM_impl,
thread,
EGLPERFSTATSGETBRCM_ID,
RPC_INT(buffer_len),
RPC_BOOLEAN(reset),
buffer);
}
#endif
#if EGL_BRCM_mem_usage
EGLAPI void eglProcessMemUsageGetBRCM(uint32_t id_0, uint32_t id_1, char *buffer, uint32_t buffer_len)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
RPC_CALL4_OUT_BULK(eglIntGetProcessMemUsage_impl,
thread,
EGLINTGETPROCESSMEMUSAGE_ID,
RPC_UINT(id_0),
RPC_UINT(id_1),
RPC_UINT(buffer_len),
buffer);
}
#endif

View File

@@ -0,0 +1,29 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_client.h"
void egl_perf_monitor_term(CLIENT_PROCESS_STATE_T *process);

View File

@@ -0,0 +1,412 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#define VCOS_LOG_CATEGORY (&egl_khr_image_client_log)
#include "interface/khronos/common/khrn_client_mangle.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/include/EGL/eglext_brcm.h"
#include "interface/khronos/include/GLES/gl.h"
#include "interface/vcos/vcos.h"
#if EGL_ANDROID_image_native_buffer
#include <gralloc_brcm.h>
#endif
#if defined(ANDROID) && defined(KHRN_BCG_ANDROID)
#include "gralloc_priv.h"
#include "middleware/khronos/common/2708/khrn_prod_4.h"
#endif
static VCOS_LOG_CAT_T egl_khr_image_client_log = VCOS_LOG_INIT("egl_khr_image_client", VCOS_LOG_WARN);
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLImageKHR result = EGL_NO_IMAGE_KHR;
CLIENT_LOCK();
vcos_log_info("eglCreateImageKHR: dpy %p ctx %p target %x buf %p\n",
dpy, ctx, target, buffer);
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process) {
EGL_CONTEXT_T *context;
bool ctx_error;
if (target == EGL_NATIVE_PIXMAP_KHR
#ifdef EGL_BRCM_image_wrap
|| target == EGL_IMAGE_WRAP_BRCM
#endif
#ifdef EGL_BRCM_image_wrap_bcg
|| target == EGL_IMAGE_WRAP_BRCM_BCG
#endif
#if EGL_ANDROID_image_native_buffer
|| target == EGL_NATIVE_BUFFER_ANDROID
|| target == EGL_IMAGE_BRCM_MULTIMEDIA
|| target == EGL_IMAGE_BRCM_RAW_PIXELS
#endif
|| target == EGL_IMAGE_BRCM_DUPLICATE
) {
context = NULL;
ctx_error = ctx != EGL_NO_CONTEXT;
} else {
context = client_egl_get_context(thread, process, ctx);
ctx_error = !context;
}
if (ctx_error) {
thread->error = EGL_BAD_PARAMETER;
}
else {
uint32_t buf[2];
KHRN_IMAGE_FORMAT_T buffer_format = IMAGE_FORMAT_INVALID;
uint32_t buffer_width = 0;
uint32_t buffer_height = 0;
uint32_t buffer_stride = 0;
bool buf_error = false;
if (target == EGL_NATIVE_PIXMAP_KHR) {
buf[0] = 0; buf[1] = (uint32_t)(-1);
platform_get_pixmap_server_handle((EGLNativePixmapType)buffer, buf);
#if EGL_BRCM_global_image
if ((buf[0] == 0) && (buf[1] == (uint32_t)(-1))) { /* allow either regular or global image server-side pixmaps */
#else
if ((buf[0] == 0) || (buf[1] != (uint32_t)(-1))) { /* only allow regular server-side pixmaps */
#endif
/* This is a client-side pixmap! TODO: implement these properly */
KHRN_IMAGE_WRAP_T image;
if (platform_get_pixmap_info((EGLNativePixmapType)buffer, &image))
{
//meego hack
if(image.aux!=0)
{
//image.aux refers to a server side EGL surface
//that already contains the data we're interested in
buf[0] = (uint32_t)image.aux;
target = EGL_IMAGE_FROM_SURFACE_BRCM;
khrn_platform_release_pixmap_info((EGLNativePixmapType)buffer, &image);
}
//
else
{
buf[0] = image.width | image.height << 16;
target = EGL_NATIVE_PIXMAP_CLIENT_SIDE_BRCM;
khrn_platform_release_pixmap_info((EGLNativePixmapType)buffer, &image);
}
}
else
{
buf_error = true;
}
}
#if EGL_BRCM_image_wrap
} else if (target == EGL_IMAGE_WRAP_BRCM) {
KHRN_IMAGE_WRAP_T *wrap_buffer = (KHRN_IMAGE_WRAP_T *)buffer;
buf[0] = (uint32_t)wrap_buffer->storage;
buffer_format = wrap_buffer->format;
buffer_width = wrap_buffer->width;
buffer_height = wrap_buffer->height;
buffer_stride = wrap_buffer->stride;
#endif
#if EGL_BRCM_image_wrap_bcg
} else if (target == EGL_IMAGE_WRAP_BRCM_BCG) {
EGL_IMAGE_WRAP_BRCM_BCG_IMAGE_T *wrap_buffer = (EGL_IMAGE_WRAP_BRCM_BCG_IMAGE_T *)buffer;
buf[0] = (uint32_t)wrap_buffer->storage;
buffer_width = wrap_buffer->width;
buffer_height = wrap_buffer->height;
buffer_stride = wrap_buffer->stride;
switch(wrap_buffer->format)
{
case BEGL_BufferFormat_eR8G8B8A8_TFormat: buffer_format = ABGR_8888_TF; break;
case BEGL_BufferFormat_eX8G8B8A8_TFormat: buffer_format = XBGR_8888_TF; break;
case BEGL_BufferFormat_eR5G6B5_TFormat: buffer_format = RGB_565_TF; break;
case BEGL_BufferFormat_eR5G5B5A1_TFormat: buffer_format = RGBA_5551_TF; break;
case BEGL_BufferFormat_eR4G4B4A4_TFormat: buffer_format = RGBA_4444_TF; break;
case BEGL_BufferFormat_eR8G8B8A8_LTFormat: buffer_format = ABGR_8888_LT; break;
case BEGL_BufferFormat_eX8G8B8A8_LTFormat: buffer_format = XBGR_8888_LT; break;
case BEGL_BufferFormat_eR5G6B5_LTFormat: buffer_format = RGB_565_LT; break;
case BEGL_BufferFormat_eR5G5B5A1_LTFormat: buffer_format = RGBA_5551_LT; break;
case BEGL_BufferFormat_eR4G4B4A4_LTFormat: buffer_format = RGBA_4444_LT; break;
default:
buf_error = true;
}
#endif
#if EGL_ANDROID_image_native_buffer
#ifdef KHRN_BCG_ANDROID
} else if (target == EGL_NATIVE_BUFFER_ANDROID) {
android_native_buffer_t *android_buffer = (android_native_buffer_t *)buffer;
vcos_assert(ANDROID_NATIVE_BUFFER_MAGIC == android_buffer->common.magic);
/* TODO check that handle is a valid gralloc handle */
/* These are shadow width/height and format, not to be confused with the
underlying formats configuration */
buf[0] = (uint32_t)khrn_hw_unaddr(((struct private_handle_t *)android_buffer->handle)->oglPhysicalAddress);
buffer_format = ((struct private_handle_t *)android_buffer->handle)->oglFormat;
buffer_width = android_buffer->width;
buffer_height = android_buffer->height;
buffer_stride = ((struct private_handle_t *)android_buffer->handle)->oglStride;
switch (((struct private_handle_t *)android_buffer->handle)->oglFormat)
{
case BEGL_BufferFormat_eR8G8B8A8_TFormat: buffer_format = ABGR_8888_TF; break;
case BEGL_BufferFormat_eX8G8B8A8_TFormat: buffer_format = XBGR_8888_TF; break;
case BEGL_BufferFormat_eR5G6B5_TFormat: buffer_format = RGB_565_TF; break;
case BEGL_BufferFormat_eR5G5B5A1_TFormat: buffer_format = RGBA_5551_TF; break;
case BEGL_BufferFormat_eR4G4B4A4_TFormat: buffer_format = RGBA_4444_TF; break;
case BEGL_BufferFormat_eR8G8B8A8_LTFormat: buffer_format = ABGR_8888_LT; break;
case BEGL_BufferFormat_eX8G8B8A8_LTFormat: buffer_format = XBGR_8888_LT; break;
case BEGL_BufferFormat_eR5G6B5_LTFormat: buffer_format = RGB_565_LT; break;
case BEGL_BufferFormat_eR5G5B5A1_LTFormat: buffer_format = RGBA_5551_LT; break;
case BEGL_BufferFormat_eR4G4B4A4_LTFormat: buffer_format = RGBA_4444_LT; break;
default : buf_error = true; break;
}
#else
} else if (target == EGL_NATIVE_BUFFER_ANDROID) {
gralloc_private_handle_t *gpriv = gralloc_private_handle_from_client_buffer(buffer);
int res_type = gralloc_private_handle_get_res_type(gpriv);
if (res_type == GRALLOC_PRIV_TYPE_GL_RESOURCE) {
/* just return the a copy of the EGLImageKHR gralloc created earlier
see hardware/broadcom/videocore/components/graphics/gralloc/ */
target = EGL_IMAGE_BRCM_DUPLICATE;
buf[0] = (uint32_t)gralloc_private_handle_get_egl_image(gpriv);
vcos_log_trace("%s: converting buffer %p egl_image %d to EGL_IMAGE_BRCM_DUPLICATE",
__FUNCTION__, buffer, buf[0]);
}
else if (res_type == GRALLOC_PRIV_TYPE_MM_RESOURCE) {
/* MM image is potentially going to be used as a texture so
* VC EGL needs to acquire a reference to the underlying vc_image.
* So, we create the image in the normal way.
* EGL_NATIVE_BUFFER_ANDROID is passed as the target.
*/
if (gpriv->gl_format == GRALLOC_MAGICS_HAL_PIXEL_FORMAT_OPAQUE)
target = EGL_IMAGE_BRCM_MULTIMEDIA;
else
target = EGL_IMAGE_BRCM_RAW_PIXELS;
buffer_width = gpriv->w;
buffer_height = gpriv->h;
buffer_stride = gpriv->stride;
buf[0] = gralloc_private_handle_get_vc_handle(gpriv);
vcos_log_trace("%s: converting buffer %p handle %u to EGL_IMAGE_BRCM_MULTIMEDIA",
__FUNCTION__, buffer, buf[0]);
}
else {
vcos_log_error("%s: unknown gralloc resource type %x", __FUNCTION__, res_type);
}
#endif
#endif
} else {
vcos_log_trace("%s:target type %x buffer %p handled on server", __FUNCTION__, target, buffer);
buf[0] = (uint32_t)buffer;
}
if (buf_error) {
thread->error = EGL_BAD_PARAMETER;
}
else {
EGLint texture_level = 0;
bool attr_error = false;
if (attr_list) {
while (!attr_error && *attr_list != EGL_NONE) {
switch (*attr_list++) {
case EGL_GL_TEXTURE_LEVEL_KHR:
texture_level = *attr_list++;
break;
case EGL_IMAGE_PRESERVED_KHR:
{
EGLint preserved = *attr_list++;
if ((preserved != EGL_FALSE) && (preserved != EGL_TRUE)) {
attr_error = true;
} /* else: ignore the actual value -- we always preserve */
break;
}
default:
attr_error = true;
}
}
}
if (attr_error) {
thread->error = EGL_BAD_PARAMETER;
}
else {
#if EGL_BRCM_global_image
if ((target == EGL_NATIVE_PIXMAP_KHR) && (buf[1] != (uint32_t)-1)) {
if (platform_use_global_image_as_egl_image(buf[0], buf[1], (EGLNativePixmapType)buffer, &thread->error)) {
if (!khrn_global_image_map_insert(&process->global_image_egl_images,
process->next_global_image_egl_image,
buf[0] | ((uint64_t)buf[1] << 32))) {
thread->error = EGL_BAD_ALLOC;
} else {
result = (EGLImageKHR)(uintptr_t)process->next_global_image_egl_image;
thread->error = EGL_SUCCESS;
do {
process->next_global_image_egl_image = (1 << 31) |
(process->next_global_image_egl_image + 1);
} while (khrn_global_image_map_lookup(&process->global_image_egl_images,
process->next_global_image_egl_image));
}
}
} else
#endif
{
EGLint results[2];
vcos_log_info("%s: width %d height %d target %x buffer %p", __FUNCTION__, buffer_width, buffer_height, target, buffer);
RPC_CALL10_OUT_CTRL(eglCreateImageKHR_impl,
thread,
EGLCREATEIMAGEKHR_ID,
RPC_UINT(context ? (context->type == OPENGL_ES_20 ? 2 : 1) : 0),
RPC_UINT(context ? context->servercontext : 0),
RPC_ENUM(target),
RPC_UINT(buf[0]),
RPC_UINT(buffer_format),
RPC_UINT(buffer_width),
RPC_UINT(buffer_height),
RPC_UINT(buffer_stride),
RPC_INT(texture_level),
results);
result = (EGLImageKHR)(intptr_t)results[0];
thread->error = results[1];
if (target == EGL_NATIVE_PIXMAP_CLIENT_SIDE_BRCM || target == EGL_IMAGE_FROM_SURFACE_BRCM)
{
khrn_platform_bind_pixmap_to_egl_image((EGLNativePixmapType)buffer, result, target == EGL_NATIVE_PIXMAP_CLIENT_SIDE_BRCM);
}
}
}
}
}
}
}
CLIENT_UNLOCK();
if (result == EGL_NO_IMAGE_KHR) {
vcos_log_error("%s: failed to create image for buffer %p target %d error 0x%x",
__FUNCTION__, buffer, target, thread->error);
} else {
vcos_log_trace("%s: returning EGLImageKHR %p for buffer %p target %d",
__FUNCTION__, result, buffer, target);
}
return result;
}
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
vcos_log_trace("eglDestroyImageKHR image=%d.\n", (int)image);
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
vcos_log_trace("%s: process %p image %p", __FUNCTION__, process, image);
if (!process)
result = EGL_FALSE;
else {
khrn_platform_unbind_pixmap_from_egl_image(image);
#if EGL_BRCM_global_image
if ((uintptr_t)image & (1 << 31)) {
result = khrn_global_image_map_delete(&process->global_image_egl_images, (uint32_t)(uintptr_t)image) ?
EGL_TRUE : EGL_FALSE;
} else
#endif
{
vcos_log_trace("%s: process %p image %p calling eglDestroyImageKHR_impl",
__FUNCTION__, process, image);
result = RPC_BOOLEAN_RES(RPC_CALL1_RES(eglDestroyImageKHR_impl,
thread,
EGLDESTROYIMAGEKHR_ID,
RPC_EGLID(image)));
}
if (!result) {
thread->error = EGL_BAD_PARAMETER;
}
}
}
CLIENT_UNLOCK();
return result;
}
void eglIntImageSetColorData(EGLDisplay dpy,
EGLImageKHR image, KHRN_IMAGE_FORMAT_T format,
uint32_t x_offset, uint32_t y_offset,
uint32_t width, uint32_t height,
int32_t stride, const void *data)
{
CLIENT_THREAD_STATE_T *thread;
CLIENT_PROCESS_STATE_T *process;
if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) {
size_t chunk = KHDISPATCH_WORKSPACE_SIZE / stride;
const uint8_t *p = (uint8_t *)data + (y_offset*stride);
size_t remaining = height;
size_t y = y_offset;
vcos_log_trace("[%s] egl im %d (%d,%d,%d,%d)",__FUNCTION__, (uint32_t)image, x_offset, y_offset, width, height);
while (remaining) {
size_t n = _min(remaining, chunk);
size_t size = n * stride;
RPC_CALL8_IN_BULK(eglIntImageSetColorData_impl,
thread, EGLINTIMAGESETCOLORDATA_ID,
RPC_UINT(image), format, x_offset, y, width, n, stride,
p, size);
p += size;
y += n;
remaining -= n;
}
CLIENT_UNLOCK();
}
}

View File

@@ -0,0 +1,190 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_client_mangle.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/egl/egl_client_config.h"
#ifdef RPC_DIRECT
#include "interface/khronos/egl/egl_int_impl.h"
#endif
#include <assert.h>
static bool lock_surface_check_attribs(const EGLint *attrib_list, bool *preserve_pixels, uint32_t *lock_usage_hint)
{
if (!attrib_list)
return EGL_TRUE;
while (1) {
int name = *attrib_list++;
if (name == EGL_NONE)
return EGL_TRUE;
else {
int value = *attrib_list++;
switch (name) {
case EGL_MAP_PRESERVE_PIXELS_KHR:
*preserve_pixels = value ? true : false;
break;
case EGL_LOCK_USAGE_HINT_KHR:
if (value & ~(EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR))
return EGL_FALSE;
*lock_usage_hint = value;
break;
default:
return EGL_FALSE;
}
}
}
}
EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surf, const EGLint *attrib_list)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (!process)
result = 0;
else {
EGL_SURFACE_T *surface = client_egl_get_surface(thread, process, surf);
if (surface) {
bool preserve_pixels = false;
uint32_t lock_usage_hint = EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR; /* we completely ignore this */
assert(!surface->is_locked);
if (!lock_surface_check_attribs(attrib_list, &preserve_pixels, &lock_usage_hint)) {
thread->error = EGL_BAD_ATTRIBUTE;
result = EGL_FALSE;
} else if (!egl_config_is_lockable((int)(intptr_t)surface->config - 1)) {
/* Only lockable surfaces can be locked (obviously) */
thread->error = EGL_BAD_ACCESS;
result = EGL_FALSE;
} else if (surface->context_binding_count) {
/* Cannot lock a surface if it is bound to a context */
thread->error = EGL_BAD_ACCESS;
result = EGL_FALSE;
} else if (preserve_pixels) {
/* TODO: we don't need to support this. What error should we return? */
thread->error = EGL_BAD_ATTRIBUTE;
return EGL_FALSE;
} else {
/* Don't allocate the buffer here. This happens during "mapping", in eglQuerySurface. */
surface->mapped_buffer = 0;
surface->is_locked = true;
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
}
} else
result = EGL_FALSE;
}
}
CLIENT_UNLOCK();
return result;
}
EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surf)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (!process)
result = 0;
else {
EGL_SURFACE_T *surface = client_egl_get_locked_surface(thread, process, surf);
if (!surface) {
result = EGL_FALSE;
} else if (!surface->is_locked) {
thread->error = EGL_BAD_ACCESS;
result = EGL_FALSE;
} else {
assert(surface->is_locked);
if (surface->mapped_buffer) {
KHRN_IMAGE_FORMAT_T format = egl_config_get_mapped_format((int)(intptr_t)surface->config - 1);
uint32_t stride = khrn_image_get_stride(format, surface->width);
int lines, offset, height;
lines = KHDISPATCH_WORKSPACE_SIZE / stride;
offset = 0;
height = surface->height;
while (height > 0) {
int batch = _min(lines, height);
#ifndef RPC_DIRECT
uint32_t len = batch * stride;
#endif
RPC_CALL7_IN_BULK(eglIntSetColorData_impl,
thread,
EGLINTSETCOLORDATA_ID,
surface->serverbuffer,
format,
surface->width,
batch,
stride,
offset,
(const char *)surface->mapped_buffer + offset * stride,
len);
offset += batch;
height -= batch;
}
khrn_platform_free(surface->mapped_buffer);
}
surface->mapped_buffer = 0;
surface->is_locked = false;
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
}
}
}
CLIENT_UNLOCK();
return result;
}

View File

@@ -0,0 +1,405 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#ifndef SYNC_FENCE_KHR_SHORTCUT
//#define SYNC_FENCE_KHR_SHORTCUT 0 /* notifications made in driver back-end */
#define SYNC_FENCE_KHR_SHORTCUT 1 /* notifications made in dispatch */
#endif
//==============================================================================
#include "interface/khronos/common/khrn_client_mangle.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/ext/egl_khr_sync_client.h"
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
#if defined(V3D_LEAN)
#include "interface/khronos/common/khrn_int_misc_impl.h"
#endif
//==============================================================================
typedef struct {
EGLint condition;
EGLint threshold;
EGLint status;
EGLenum type;
int name[3]; // Used as ID in khronos_platform_semaphore_create
EGL_SYNC_ID_T serversync;
/*
we keep one master handle to the named semaphore in existence for the
lifetime of the sync object, allowing both wait functions and the KHAN
message handler to "open, post/wait, close".
*/
PLATFORM_SEMAPHORE_T master;
} EGL_SYNC_T;
//==============================================================================
static EGL_SYNC_T *egl_sync_create(EGLSyncKHR sync, EGLenum type,
EGLint condition, EGLint threshold, EGLint status)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGL_SYNC_T *sync_ptr = (EGL_SYNC_T *)khrn_platform_malloc(sizeof(EGL_SYNC_T), "EGL_SYNC_T");
uint64_t pid = khronos_platform_get_process_id();
uint32_t sem;
if (!sync_ptr)
return 0;
sync_ptr->condition = condition;
sync_ptr->threshold = threshold;
sync_ptr->type = type;
sync_ptr->status = status;
sync_ptr->name[0] = (int)pid;
sync_ptr->name[1] = (int)(pid >> 32);
sync_ptr->name[2] = (int)sync;
if (khronos_platform_semaphore_create(&sync_ptr->master, sync_ptr->name, 0) != KHR_SUCCESS) {
khrn_platform_free(sync_ptr);
return 0;
}
sem = (uint32_t) sync;
#if SYNC_FENCE_KHR_SHORTCUT == 1
if (type == EGL_SYNC_FENCE_KHR){
RPC_CALL3(eglIntCreateSyncFence_impl,
thread,
EGLINTCREATESYNCFENCE_ID,
RPC_UINT(condition),
RPC_INT(threshold),
RPC_UINT(sem));
} else
#endif
{
sync_ptr->serversync = RPC_UINT_RES(RPC_CALL4_RES(eglIntCreateSync_impl,
thread,
EGLINTCREATESYNC_ID,
RPC_UINT(type),
RPC_UINT(condition),
RPC_INT(threshold),
RPC_UINT(sem)));
if (!sync_ptr->serversync) {
khronos_platform_semaphore_destroy(&sync_ptr->master);
khrn_platform_free(sync_ptr);
return 0;
}
}
return sync_ptr;
}
//------------------------------------------------------------------------------
static void egl_sync_term(EGL_SYNC_T *sync_master)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
#if SYNC_FENCE_KHR_SHORTCUT == 1
if (sync_master->type != EGL_SYNC_FENCE_KHR)
#endif
{
RPC_CALL1(eglIntDestroySync_impl,
thread,
EGLINTDESTROYSYNC_ID,
RPC_UINT(sync_master->serversync));
}
khronos_platform_semaphore_destroy(&sync_master->master);
}
//------------------------------------------------------------------------------
static void egl_sync_destroy_iterator
(KHRN_POINTER_MAP_T *sync_map, uint32_t sync, void *sync_handle, void *data)
{
EGL_SYNC_T *sync_ptr = (EGL_SYNC_T *) sync;
UNUSED(sync_map);
UNUSED(sync_handle);
UNUSED(data);
vcos_assert(sync_ptr != NULL);
egl_sync_term(sync_ptr);
khrn_platform_free(sync_ptr);
}
//------------------------------------------------------------------------------
static EGLBoolean egl_sync_check_attribs(const EGLint *attrib_list, EGLenum type,
EGLint *condition, EGLint *threshold, EGLint *status)
{
switch (type) {
case EGL_SYNC_FENCE_KHR:
*condition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
*threshold = 0;
*status = EGL_UNSIGNALED_KHR;
break;
default :
*condition = EGL_NONE;
*threshold = 0;
*status = 0;
break;
}
if (attrib_list) {
while (1) {
int name = *attrib_list++;
if (name == EGL_NONE)
break;
else {
/* int value = * */attrib_list++; /* at present no name/value pairs are handled */
switch (name) {
default:
return EGL_FALSE;
}
}
}
}
return ((type == EGL_SYNC_FENCE_KHR) || (type == 0));
}
//------------------------------------------------------------------------------
static EGLBoolean egl_sync_get_attrib(EGL_SYNC_T *sync, EGLint attrib, EGLint *value)
{
switch (attrib) {
case EGL_SYNC_TYPE_KHR:
*value = sync->type;
return EGL_TRUE;
case EGL_SYNC_STATUS_KHR:
*value = sync->status;
return EGL_TRUE;
case EGL_SYNC_CONDITION_KHR:
*value = sync->condition;
return EGL_TRUE;
default:
return EGL_FALSE;
}
}
//==============================================================================
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLSyncKHR sync = EGL_NO_SYNC_KHR;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
EGLint condition;
EGLint threshold;
EGLint status;
if (process)
{
if (egl_sync_check_attribs(attrib_list, type, &condition, &threshold, &status)) {
EGL_SYNC_T *sync_ptr = egl_sync_create((EGLSyncKHR)(size_t)process->next_sync, type, condition, threshold, status);
if (sync_ptr) {
if (khrn_pointer_map_insert(&process->syncs, process->next_sync, sync_ptr)) {
thread->error = EGL_SUCCESS;
sync = (EGLSurface)(size_t)process->next_sync++;
} else {
thread->error = EGL_BAD_ALLOC;
egl_sync_term(sync_ptr);
khrn_platform_free(sync_ptr);
}
} else
thread->error = EGL_BAD_ALLOC;
}
}
}
CLIENT_UNLOCK();
return sync;
}
//------------------------------------------------------------------------------
// TODO: should we make sure any syncs have come back before destroying the object?
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process) {
EGL_SYNC_T *sync_ptr = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)sync);
if (sync_ptr) {
thread->error = EGL_SUCCESS;
khrn_pointer_map_delete(&process->syncs, (uint32_t)(uintptr_t)sync);
egl_sync_term(sync_ptr);
khrn_platform_free(sync_ptr);
} else
thread->error = EGL_BAD_PARAMETER;
result = (thread->error == EGL_SUCCESS ? EGL_TRUE : EGL_FALSE);
} else {
result = EGL_FALSE;
}
}
CLIENT_UNLOCK();
return result;
}
//------------------------------------------------------------------------------
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
UNUSED(timeout);
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process) {
EGL_SYNC_T *sync_ptr = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)sync);
if (sync_ptr) {
PLATFORM_SEMAPHORE_T semaphore;
if( khronos_platform_semaphore_create(&semaphore, sync_ptr->name, 1) == KHR_SUCCESS) {
if (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR)
RPC_FLUSH(thread);
CLIENT_UNLOCK();
khronos_platform_semaphore_acquire(&semaphore);
khronos_platform_semaphore_release(&semaphore);
khronos_platform_semaphore_destroy(&semaphore);
return EGL_CONDITION_SATISFIED_KHR;
} else
thread->error = EGL_BAD_ALLOC; // not strictly allowed by the spec, but indicates that we failed to create a reference to the named semaphore
} else
thread->error = EGL_BAD_PARAMETER;
}
}
CLIENT_UNLOCK();
return EGL_FALSE;
}
//------------------------------------------------------------------------------
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
UNUSED(mode);
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process) {
EGL_SYNC_T *sync_ptr = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)sync);
if (sync_ptr)
thread->error = EGL_BAD_MATCH;
else
thread->error = EGL_BAD_PARAMETER;
}
}
CLIENT_UNLOCK();
return EGL_FALSE;
}
//------------------------------------------------------------------------------
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
EGLBoolean result = EGL_FALSE;
CLIENT_LOCK();
{
CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE);
if (process)
{
if (value)
{
EGL_SYNC_T *sync_ptr = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)sync);
if (sync_ptr) {
if (egl_sync_get_attrib(sync_ptr, attribute, value)) {
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
} else
thread->error = EGL_BAD_ATTRIBUTE;
} else
thread->error = EGL_BAD_PARAMETER;
}
else
{
thread->error = EGL_BAD_PARAMETER;
}
}
}
CLIENT_UNLOCK();
return result;
}
//------------------------------------------------------------------------------
void egl_sync_destroy_all(KHRN_POINTER_MAP_T *sync_map)
{
khrn_pointer_map_iterate(sync_map, egl_sync_destroy_iterator, NULL);
}
//==============================================================================

View File

@@ -0,0 +1,35 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/common/khrn_client.h"
#ifdef RPC_DIRECT
#include "middleware/khronos/egl/egl_server.h"
#endif
void egl_sync_destroy_all(KHRN_POINTER_MAP_T *sync_map);

View File

@@ -0,0 +1,45 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EGL_EGLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/ext/egl_openmaxil_client.h"
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include <assert.h>
int eglIntOpenMAXILDoneMarker (void* component_handle, EGLImageKHR egl_image)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
int res;
res = RPC_INT_RES(RPC_CALL2_RES(eglIntOpenMAXILDoneMarker_impl,
thread, EGLINTOPENMAXILDONEMARKER_ID, RPC_EGLID(component_handle), RPC_EGLID(egl_image)));
return res;
}

View File

@@ -0,0 +1,31 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "interface/khronos/include/EGL/egl.h"
#include "interface/khronos/include/EGL/eglext.h"
extern int eglIntOpenMAXILDoneMarker (void* component_handle, EGLImageKHR egl_image);

View File

@@ -0,0 +1,71 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_client_mangle.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/glxx_int_impl.h"
#include "interface/khronos/glxx/gl20_int_impl.h"
#endif
#include "interface/khronos/include/GLES2/gl2.h"
#include "interface/khronos/include/GLES2/gl2ext.h"
GL_API void GL_APIENTRY glInsertEventMarkerEXT(GLsizei length, const GLchar *marker)
{
/* Do nothing.
When SpyHook is enabled, it will trap this function and pass to SpyTool.
That's all that is needed
*/
UNUSED(length);
UNUSED(marker);
}
GL_API void GL_APIENTRY glPushGroupMarkerEXT(GLsizei length, const GLchar *marker)
{
/* Do nothing.
When SpyHook is enabled, it will trap this function and pass to SpyTool.
That's all that is needed
*/
UNUSED(length);
UNUSED(marker);
}
GL_API void GL_APIENTRY glPopGroupMarkerEXT(void)
{
/* Do nothing.
When SpyHook is enabled, it will trap this function and pass to SpyTool.
That's all that is needed
*/
}

View File

@@ -0,0 +1,95 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_client_mangle.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/glxx_int_impl.h"
#include "interface/khronos/glxx/gl11_int_impl.h"
#endif
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/GLES/glext.h"
/* GL_OES_draw_texture */
GL_API void GL_APIENTRY glDrawTexsOES (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
{
glDrawTexfOES((GLfloat)x,(GLfloat)y,(GLfloat)x, (GLfloat)width,(GLfloat)height);
}
GL_API void GL_APIENTRY glDrawTexiOES (GLint x, GLint y, GLint z, GLint width, GLint height)
{
glDrawTexfOES((GLfloat)x,(GLfloat)y,(GLfloat)x, (GLfloat)width,(GLfloat)height);
}
GL_API void GL_APIENTRY glDrawTexxOES (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
{
glDrawTexfOES(fixed_to_float(x), fixed_to_float(y), fixed_to_float(x), fixed_to_float(width), fixed_to_float(height));
}
GL_API void GL_APIENTRY glDrawTexsvOES (const GLshort *coords)
{
glDrawTexfOES((GLfloat)coords[0],(GLfloat)coords[1],(GLfloat)coords[2], (GLfloat)coords[3],(GLfloat)coords[4]);
}
GL_API void GL_APIENTRY glDrawTexivOES (const GLint *coords)
{
glDrawTexfOES((GLfloat)coords[0],(GLfloat)coords[1],(GLfloat)coords[2], (GLfloat)coords[3],(GLfloat)coords[4]);
}
GL_API void GL_APIENTRY glDrawTexxvOES (const GLfixed *coords)
{
glDrawTexfOES(fixed_to_float(coords[0]), fixed_to_float(coords[1]), fixed_to_float(coords[2]), fixed_to_float(coords[3]), fixed_to_float(coords[4]));
}
GL_API void GL_APIENTRY glDrawTexfOES (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (IS_OPENGLES_11(thread)) {
RPC_CALL5(glDrawTexfOES_impl_11,
thread,
GLDRAWTEXFOES_ID_11,
RPC_FLOAT(x),
RPC_FLOAT(y),
RPC_FLOAT(z),
RPC_FLOAT(width),
RPC_FLOAT(height));
}
}
GL_API void GL_APIENTRY glDrawTexfvOES (const GLfloat *coords)
{
glDrawTexfOES((GLfloat)coords[0],(GLfloat)coords[1],(GLfloat)coords[2], (GLfloat)coords[3],(GLfloat)coords[4]);
}

View File

@@ -0,0 +1,153 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#define VCOS_LOG_CATEGORY (&gl_oes_egl_image_client_log)
#include "interface/khronos/common/khrn_client_mangle.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/glxx_int_impl.h"
#include "interface/khronos/glxx/gl20_int_impl.h"
#endif
#include "interface/khronos/include/GLES2/gl2.h"
#include "interface/khronos/include/GLES2/gl2ext.h"
VCOS_LOG_CAT_T gl_oes_egl_image_client_log = VCOS_LOG_INIT("gl_oes_egl_image", VCOS_LOG_WARN);
static void set_error(GLXX_CLIENT_STATE_T *state, GLenum error)
{
if (state->error == GL_NO_ERROR)
state->error = error;
}
static bool check_global_image_egl_image(GLuint global_image_id[2],
GLeglImageOES image, CLIENT_THREAD_STATE_T *thread,
bool render) /* else texture */
{
CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
uint64_t id;
uint32_t format, width, height;
CLIENT_LOCK();
id = process->inited ? khrn_global_image_map_lookup(&process->global_image_egl_images, (uint32_t)(uintptr_t)image) : 0;
CLIENT_UNLOCK();
if (!id) {
return false;
}
global_image_id[0] = (GLuint)id;
global_image_id[1] = (GLuint)(id >> 32);
platform_get_global_image_info(global_image_id[0], global_image_id[1], &format, &width, &height);
if (!(format & ((thread->opengl.context->type == OPENGL_ES_11) ?
(render ? EGL_PIXEL_FORMAT_RENDER_GLES_BRCM : EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM) :
(render ? EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM : EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM))) ||
(width == 0) || (height == 0)) {
return false;
}
/* format and max width/height checks done on server */
return true;
}
GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (IS_OPENGLES_11_OR_20(thread)) {
#if EGL_BRCM_global_image
if ((uintptr_t)image & (1u << 31)) {
GLuint global_image_id[2];
if (check_global_image_egl_image(global_image_id, image, thread, false)) {
RPC_CALL3(glGlobalImageTexture2DOES_impl,
thread,
GLGLOBALIMAGETEXTURE2DOES_ID,
RPC_ENUM(target),
RPC_UINT(global_image_id[0]),
RPC_UINT(global_image_id[1]));
} else {
set_error(GLXX_GET_CLIENT_STATE(thread), GL_INVALID_VALUE);
}
} else {
#endif
vcos_log_trace("[%s] target 0x%x image %d", __FUNCTION__, target, (uint32_t)image);
RPC_CALL2(glEGLImageTargetTexture2DOES_impl,
thread,
GLEGLIMAGETARGETTEXTURE2DOES_ID,
RPC_ENUM(target),
RPC_EGLID(image));
RPC_FLUSH(thread);
#if EGL_BRCM_global_image
}
#endif
}
}
GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (IS_OPENGLES_11(thread)) {
/* OES_framebuffer_object not supported for GLES1.1 */
GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
if (state->error == GL_NO_ERROR)
state->error = GL_INVALID_OPERATION;
}
else if (IS_OPENGLES_20(thread)) {
#if EGL_BRCM_global_image
if ((uintptr_t)image & (1u << 31)) {
GLuint global_image_id[2];
if (check_global_image_egl_image(global_image_id, image, thread, true)) {
RPC_CALL3(glGlobalImageRenderbufferStorageOES_impl_20,
thread,
GLGLOBALIMAGERENDERBUFFERSTORAGEOES_ID_20,
RPC_ENUM(target),
RPC_UINT(global_image_id[0]),
RPC_UINT(global_image_id[1]));
} else {
set_error(GLXX_GET_CLIENT_STATE(thread), GL_INVALID_VALUE);
}
} else {
#endif
RPC_CALL2(glEGLImageTargetRenderbufferStorageOES_impl_20,
thread,
GLEGLIMAGETARGETRENDERBUFFERSTORAGEOES_ID_20,
RPC_ENUM(target),
RPC_EGLID(image));
#if EGL_BRCM_global_image
}
#endif
}
}

View File

@@ -0,0 +1,134 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_client_mangle.h"
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/glxx_int_impl.h"
#include "interface/khronos/glxx/gl11_int_impl.h"
#endif
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/GLES/glext.h"
extern GLboolean glxx_client_IsRenderbuffer(GLuint renderbuffer);
extern void glxx_client_BindRenderbuffer(GLenum target, GLuint renderbuffer);
extern void glxx_client_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
extern void glxx_client_GenRenderbuffers(GLsizei n, GLuint *renderbuffers);
extern void glxx_client_RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
extern void glxx_client_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
extern GLboolean glxx_client_IsFramebuffer(GLuint framebuffer);
extern void glxx_client_BindFramebuffer(GLenum target, GLuint framebuffer);
extern void glxx_client_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
extern void glxx_client_GenFramebuffers(GLsizei n, GLuint *framebuffers);
extern GLenum glxx_client_CheckFramebufferStatus(GLenum target);
extern void glxx_client_FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
extern void glxx_client_FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
extern void glxx_client_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params);
extern void glxx_client_GenerateMipmap(GLenum target);
GL_API GLboolean GL_APIENTRY glIsRenderbufferOES (GLuint renderbuffer)
{
return glxx_client_IsRenderbuffer(renderbuffer);
}
GL_API void GL_APIENTRY glBindRenderbufferOES (GLenum target, GLuint renderbuffer)
{
glxx_client_BindRenderbuffer(target, renderbuffer);
}
GL_API void GL_APIENTRY glDeleteRenderbuffersOES (GLsizei n, const GLuint* renderbuffers)
{
glxx_client_DeleteRenderbuffers(n, renderbuffers);
}
GL_API void GL_APIENTRY glGenRenderbuffersOES (GLsizei n, GLuint* renderbuffers)
{
glxx_client_GenRenderbuffers(n, renderbuffers);
}
GL_API void GL_APIENTRY glRenderbufferStorageOES (GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
glxx_client_RenderbufferStorage(target, internalformat, width, height);
}
GL_API void GL_APIENTRY glGetRenderbufferParameterivOES (GLenum target, GLenum pname, GLint* params)
{
glxx_client_GetRenderbufferParameteriv(target, pname, params);
}
GL_API GLboolean GL_APIENTRY glIsFramebufferOES (GLuint framebuffer)
{
return glxx_client_IsFramebuffer(framebuffer);
}
GL_API void GL_APIENTRY glBindFramebufferOES (GLenum target, GLuint framebuffer)
{
glxx_client_BindFramebuffer(target, framebuffer);
}
GL_API void GL_APIENTRY glDeleteFramebuffersOES (GLsizei n, const GLuint* framebuffers)
{
glxx_client_DeleteFramebuffers(n, framebuffers);
}
GL_API void GL_APIENTRY glGenFramebuffersOES (GLsizei n, GLuint* framebuffers)
{
glxx_client_GenFramebuffers(n, framebuffers);
}
GL_API GLenum GL_APIENTRY glCheckFramebufferStatusOES (GLenum target)
{
return glxx_client_CheckFramebufferStatus(target);
}
GL_API void GL_APIENTRY glFramebufferRenderbufferOES (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
glxx_client_FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
}
GL_API void GL_APIENTRY glFramebufferTexture2DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
glxx_client_FramebufferTexture2D(target, attachment, textarget, texture, level);
}
GL_API void GL_APIENTRY glGetFramebufferAttachmentParameterivOES (GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
glxx_client_GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
}
GL_API void GL_APIENTRY glGenerateMipmapOES (GLenum target)
{
glxx_client_GenerateMipmap(target);
}

View File

@@ -0,0 +1,195 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/glxx_int_impl.h"
#include "interface/khronos/glxx/gl11_int_impl.h"
#endif
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/GLES/glext.h"
GL_API void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
void *pointer = 0;
if (IS_OPENGLES_11_OR_20(thread)) {
GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
if(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER)
{
glxx_set_error(state, GL_INVALID_ENUM);
}
else if(access != GL_WRITE_ONLY_OES)
{
glxx_set_error(state, GL_INVALID_ENUM);
}
else
{
GLXX_BUFFER_INFO_T buffer;
glxx_buffer_info_get(state, target, &buffer);
if(buffer.id !=0 && buffer.cached_size > 0)
{
if(buffer.mapped_pointer != 0)
{
/* already mapped */
glxx_set_error(state, GL_INVALID_OPERATION);
}
else
{
pointer = khrn_platform_malloc(buffer.cached_size,"glxx_mapped_buffer");
if(pointer != 0)
{
buffer.mapped_pointer = pointer;
buffer.mapped_size = buffer.cached_size;
}
else
{
buffer.mapped_pointer = 0;
buffer.mapped_size = 0;
glxx_set_error(state, GL_OUT_OF_MEMORY);
}
glxx_buffer_info_set(state, target, &buffer);
}
}
else
{
glxx_set_error(state, GL_INVALID_OPERATION);
}
}
}
/*
RPC_CALL3_OUT_CTRL(glMapBufferOES_impl,
thread,
GLMAPBUFFEROES_ID,
RPC_ENUM(target),
RPC_ENUM(access),
&pointer);
*/
return pointer;
}
GL_API GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
GLboolean success = GL_FALSE;
if (IS_OPENGLES_11_OR_20(thread)) {
//use buffer sub data to flush through
GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
if(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER)
{
glxx_set_error(state, GL_INVALID_ENUM);
}
else
{
GLXX_BUFFER_INFO_T buffer;
glxx_buffer_info_get(state, target, &buffer);
if(buffer.id !=0)
{
if(buffer.mapped_pointer)
{
void * p = buffer.mapped_pointer;
GLsizeiptr size = buffer.mapped_size;
buffer.mapped_pointer = 0;
buffer.mapped_size = 0;
glxx_buffer_info_set(state, target, &buffer);
glBufferSubData (target, 0, size, p);
khrn_platform_free(p);
}
}
}
}
/*
if (IS_OPENGLES_11_OR_20(thread)) {
success = RPC_BOOLEAN_RES(RPC_CALL1_RES(glUnmapBufferOES_impl,
thread,
GLUNMAPBUFFEROES_ID,
RPC_ENUM(target)));
*/
return success;
}
GL_API void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid ** params)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
params[0] = (void *)0;
if (IS_OPENGLES_11_OR_20(thread)) {
GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
if(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER)
{
glxx_set_error(state, GL_INVALID_ENUM);
}
else if(pname != GL_BUFFER_MAP_POINTER_OES)
{
glxx_set_error(state, GL_INVALID_ENUM);
}
else
{
GLXX_BUFFER_INFO_T buffer;
glxx_buffer_info_get(state, target, &buffer);
if(buffer.id !=0)
{
params[0] = (void *)buffer.mapped_pointer;
}
}
}
/*
RPC_CALL3_OUT_CTRL(glGetBufferPointervOES_impl,
thread,
GLGETBUFFERPOINTERVOES_ID,
RPC_ENUM(target),
RPC_ENUM(pname),
params);
*/
}

View File

@@ -0,0 +1,132 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#include "interface/khronos/glxx/gl11_int_config.h"
#include "interface/khronos/include/GLES/glext.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/gl11_int_impl.h"
#endif
#if GL_OES_matrix_palette
static void set_error(GLXX_CLIENT_STATE_T *state, GLenum e) {
if (state->error == GL_NO_ERROR) state->error = e;
}
static void set_client_state_error(GLenum e) {
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
set_error(state, e);
}
GL_API void GL_APIENTRY glCurrentPaletteMatrixOES(GLuint index) {
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (IS_OPENGLES_11(thread)) {
if (index > GL11_CONFIG_MAX_PALETTE_MATRICES_OES - 1) set_client_state_error(GL_INVALID_VALUE);
else {
RPC_CALL1(glCurrentPaletteMatrixOES_impl,
thread,
GLCURRENTPALETTEMATRIXOES_ID_11,
RPC_UINT(index) );
}
}
}
GL_API void GL_APIENTRY glLoadPaletteFromModelViewMatrixOES() {
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (IS_OPENGLES_11(thread)) {
RPC_CALL0(glLoadPaletteFromModelViewMatrixOES_impl,
thread,
GLLOADPALETTEFROMMODELVIEWMATRIXOES_ID_11);
}
}
static GLboolean is_matrix_index_type(GLenum type) {
return (type == GL_UNSIGNED_BYTE);
}
static GLboolean is_matrix_palette_size(GLint size) {
/* TODO: Should size 0 be allowed or not? */
return size > 0 && size <= GL11_CONFIG_MAX_VERTEX_UNITS_OES;
}
/* TODO: This is copied from glxx_client.c. Find a better method */
static GLboolean is_aligned( GLenum type, size_t value)
{
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
return GL_TRUE;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
return (value & 1) == 0;
case GL_FIXED:
case GL_FLOAT:
return (value & 3) == 0;
default:
UNREACHABLE();
return GL_FALSE;
}
}
GL_API void GL_APIENTRY glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
if (is_matrix_index_type(type)) {
if (is_matrix_palette_size(size) && is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
glintAttribPointer(GLXX_API_11, GL11_IX_MATRIX_INDEX, size, type, GL_FALSE, stride, pointer);
} else
glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
} else
glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
}
static GLboolean is_matrix_weight_type(GLenum type) {
return type == GL_FIXED ||
type == GL_FLOAT;
}
GL_API void GL_APIENTRY glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
if (is_matrix_weight_type(type)) {
if (is_matrix_palette_size(size) && is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
glintAttribPointer(GLXX_API_11, GL11_IX_MATRIX_WEIGHT, size, type, GL_FALSE, stride, pointer);
} else
glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
} else
glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
}
#endif /* GL_OES_matrix_palette */

View File

@@ -0,0 +1,60 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
#include "interface/khronos/common/khrn_int_common.h"
#include "interface/khronos/glxx/glxx_client.h"
#include "interface/khronos/common/khrn_client_rpc.h"
#ifdef RPC_DIRECT
#include "interface/khronos/glxx/glxx_int_impl.h"
#include "interface/khronos/glxx/gl11_int_impl.h"
#endif
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/GLES/glext.h"
GL_API GLbitfield GL_APIENTRY glQueryMatrixxOES( GLfixed mantissa[16], GLint exponent[16] )
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
if (IS_OPENGLES_11(thread)) {
int i;
RPC_CALL1_OUT_CTRL(glQueryMatrixxOES_impl_11,
thread,
GLQUERYMATRIXXOES_ID_11,
mantissa);
for(i=0;i<16;i++)
exponent[i] = 0;
return 0;
}
return 0xff; /* all components invalid */
}

View File

@@ -0,0 +1,49 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GL11_INT_CONFIG_H
#define GL11_INT_CONFIG_H
#define GL11_CONFIG_MAX_TEXTURE_UNITS 4
#define GL11_CONFIG_MAX_LIGHTS 8
#define GL11_CONFIG_MAX_PLANES 1
#define GL11_CONFIG_MAX_STACK_DEPTH 16
#define GL11_CONFIG_MIN_ALIASED_POINT_SIZE 1.0f
#define GL11_CONFIG_MAX_ALIASED_POINT_SIZE 256.0f
#define GL11_CONFIG_MIN_SMOOTH_POINT_SIZE 1.0f
#define GL11_CONFIG_MAX_SMOOTH_POINT_SIZE 256.0f
#define GL11_CONFIG_MIN_ALIASED_LINE_WIDTH 0.0f
#define GL11_CONFIG_MAX_ALIASED_LINE_WIDTH 16.0f
#define GL11_CONFIG_MIN_SMOOTH_LINE_WIDTH 0.0f
#define GL11_CONFIG_MAX_SMOOTH_LINE_WIDTH 16.0f
/* GL_OES_matrix_palette */
#define GL11_CONFIG_MAX_VERTEX_UNITS_OES 3
#define GL11_CONFIG_MAX_PALETTE_MATRICES_OES 64
#endif

View File

@@ -0,0 +1,129 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(KHRN_IMPL_STRUCT)
#define FN(type, name, args) type (*name) args;
#elif defined(KHRN_IMPL_STRUCT_INIT)
#define FN(type, name, args) name,
#else
#define FN(type, name, args) extern type name args;
#endif
//gl 1.1 specific functions
FN(void, glAlphaFunc_impl_11, (GLenum func, GLclampf ref))
FN(void, glAlphaFuncx_impl_11, (GLenum func, GLclampx ref))
FN(void, glClearColorx_impl_11, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha))
FN(void, glClearDepthx_impl_11, (GLclampx depth))
FN(void, glClientActiveTexture_impl_11, (GLenum texture))
FN(void, glClipPlanef_impl_11, (GLenum plane, const GLfloat *equation))
FN(void, glClipPlanex_impl_11, (GLenum plane, const GLfixed *equation))
FN(void, glDepthRangex_impl_11, (GLclampx zNear, GLclampx zFar))
FN(void, glFogf_impl_11, (GLenum pname, GLfloat param))
FN(void, glFogfv_impl_11, (GLenum pname, const GLfloat *params))
FN(void, glFrustumf_impl_11, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar))
FN(void, glFogx_impl_11, (GLenum pname, GLfixed param))
FN(void, glFogxv_impl_11, (GLenum pname, const GLfixed *params))
FN(void, glFrustumx_impl_11, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar))
FN(void, glGetClipPlanex_impl_11, (GLenum pname, GLfixed eqn[4]))
FN(int, glGetLightfv_impl_11, (GLenum light, GLenum pname, GLfloat *params))
FN(int, glGetLightxv_impl_11, (GLenum light, GLenum pname, GLfixed *params))
FN(int, glGetMaterialxv_impl_11, (GLenum face, GLenum pname, GLfixed *params))
FN(int, glGetMaterialfv_impl_11, (GLenum face, GLenum pname, GLfloat *params))
FN(void, glGetClipPlanef_impl_11, (GLenum pname, GLfloat eqn[4]))
FN(int, glGetFixedv_impl_11, (GLenum pname, GLfixed *params))
FN(int, glGetTexEnvfv_impl_11, (GLenum env, GLenum pname, GLfloat *params))
FN(int, glGetTexEnviv_impl_11, (GLenum env, GLenum pname, GLint *params))
FN(int, glGetTexEnvxv_impl_11, (GLenum env, GLenum pname, GLfixed *params))
FN(int, glGetTexParameterxv_impl_11, (GLenum target, GLenum pname, GLfixed *params))
FN(void, glLightModelf_impl_11, (GLenum pname, GLfloat param))
FN(void, glLightModelfv_impl_11, (GLenum pname, const GLfloat *params))
FN(void, glLightf_impl_11, (GLenum light, GLenum pname, GLfloat param))
FN(void, glLightfv_impl_11, (GLenum light, GLenum pname, const GLfloat *params))
FN(void, glLightModelx_impl_11, (GLenum pname, GLfixed param))
FN(void, glLightModelxv_impl_11, (GLenum pname, const GLfixed *params))
FN(void, glLightx_impl_11, (GLenum light, GLenum pname, GLfixed param))
FN(void, glLightxv_impl_11, (GLenum light, GLenum pname, const GLfixed *params))
FN(void, glLineWidthx_impl_11, (GLfixed width))
FN(void, glLoadIdentity_impl_11, (void))
FN(void, glLoadMatrixf_impl_11, (const GLfloat *m))
FN(void, glLoadMatrixx_impl_11, (const GLfixed *m))
FN(void, glLogicOp_impl_11, (GLenum opcode))
FN(void, glMaterialf_impl_11, (GLenum face, GLenum pname, GLfloat param))
FN(void, glMaterialfv_impl_11, (GLenum face, GLenum pname, const GLfloat *params))
FN(void, glMultMatrixf_impl_11, (const GLfloat *m))
FN(void, glOrthof_impl_11, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar))
FN(void, glPolygonOffsetx_impl_11, (GLfixed factor, GLfixed units))
FN(void, glPointParameterf_impl_11, (GLenum pname, GLfloat param))
FN(void, glPointParameterfv_impl_11, (GLenum pname, const GLfloat *params))
FN(void, glRotatef_impl_11, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
FN(void, glSampleCoveragex_impl_11, (GLclampx value, GLboolean invert))
FN(void, glScalef_impl_11, (GLfloat x, GLfloat y, GLfloat z))
FN(void, glShadeModel_impl_11, (GLenum model))
FN(void, glTexEnvf_impl_11, (GLenum target, GLenum pname, GLfloat param))
FN(void, glTexEnvfv_impl_11, (GLenum target, GLenum pname, const GLfloat *params))
FN(void, glTexEnvi_impl_11, (GLenum target, GLenum pname, GLint param))
FN(void, glTexEnviv_impl_11, (GLenum target, GLenum pname, const GLint *params))
FN(void, glTexEnvx_impl_11, (GLenum target, GLenum pname, GLfixed param))
FN(void, glTexEnvxv_impl_11, (GLenum target, GLenum pname, const GLfixed *params))
FN(void, glTexParameterx_impl_11, (GLenum target, GLenum pname, GLfixed param))
FN(void, glTexParameterxv_impl_11, (GLenum target, GLenum pname, const GLfixed *params))
FN(void, glTranslatef_impl_11, (GLfloat x, GLfloat y, GLfloat z))
FN(void, glMaterialx_impl_11, (GLenum face, GLenum pname, GLfixed param))
FN(void, glMaterialxv_impl_11, (GLenum face, GLenum pname, const GLfixed *params))
FN(void, glMatrixMode_impl_11, (GLenum mode))
FN(void, glMultMatrixx_impl_11, (const GLfixed *m))
FN(void, glOrthox_impl_11, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar))
FN(void, glPointParameterx_impl_11, (GLenum pname, GLfixed param))
FN(void, glPointParameterxv_impl_11, (GLenum pname, const GLfixed *params))
//FN(void, glPointSizePointerOES_impl_11, (void))
FN(void, glPopMatrix_impl_11, (void))
FN(void, glPushMatrix_impl_11, (void))
FN(void, glRotatex_impl_11, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z))
FN(void, glScalex_impl_11, (GLfixed x, GLfixed y, GLfixed z))
FN(void, glTranslatex_impl_11, (GLfixed x, GLfixed y, GLfixed z))
//FN(void, glColorPointer_impl_11, (void))
//FN(void, glNormalPointer_impl_11, (void))
//FN(void, glTexCoordPointer_impl_11, (GLenum unit))
//FN(void, glVertexPointer_impl_11, (void))
/*****************************************************************************************/
/* OES extension functions */
/*****************************************************************************************/
//gl 1.1 specific
FN(void, glintColor_impl_11, (float red, float green, float blue, float alpha))
FN(void, glQueryMatrixxOES_impl_11, (GLfixed mantissa[16]))
FN(void, glDrawTexfOES_impl_11, (GLfloat Xs, GLfloat Ys, GLfloat Zs, GLfloat Ws, GLfloat Hs))
#if GL_OES_matrix_palette
FN(void, glCurrentPaletteMatrixOES_impl, (GLuint index))
FN(void, glLoadPaletteFromModelViewMatrixOES_impl, (void))
//FN(void, glMatrixIndexPointerOES_impl, (void))
//FN(void, glWeightPointerOES_impl, (void))
#endif
#undef FN

View File

@@ -0,0 +1,118 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(KHRN_IMPL_STRUCT)
#define FN(type, name, args) type (*name) args;
#elif defined(KHRN_IMPL_STRUCT_INIT)
#define FN(type, name, args) name,
#else
#define FN(type, name, args) extern type name args;
#endif
//gl 2.0 specific
FN(void, glAttachShader_impl_20, (GLuint program, GLuint shader))
FN(void, glBindAttribLocation_impl_20, (GLuint program, GLuint index, const char *name))
FN(void, glBlendColor_impl_20, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) // S
FN(void, glBlendEquationSeparate_impl_20, (GLenum modeRGB, GLenum modeAlpha)) // S
FN(GLuint, glCreateProgram_impl_20, (void))
FN(GLuint, glCreateShader_impl_20, (GLenum type))
FN(void, glDeleteProgram_impl_20, (GLuint program))
FN(void, glDeleteShader_impl_20, (GLuint shader))
FN(void, glDetachShader_impl_20, (GLuint program, GLuint shader))
//FN(void, glDisableVertexAttribArray_impl_20, (GLuint index))
//FN(void, glEnableVertexAttribArray_impl_20, (GLuint index))
FN(void, glGetActiveAttrib_impl_20, (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name))
FN(void, glGetActiveUniform_impl_20, (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name))
FN(void, glGetAttachedShaders_impl_20, (GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders))
FN(int, glGetAttribLocation_impl_20, (GLuint program, const char *name))
FN(int, glGetProgramiv_impl_20, (GLuint program, GLenum pname, GLint *params))
FN(void, glGetProgramInfoLog_impl_20, (GLuint program, GLsizei bufsize, GLsizei *length, char *infolog))
FN(int, glGetUniformfv_impl_20, (GLuint program, GLint location, GLfloat *params))
FN(int, glGetUniformiv_impl_20, (GLuint program, GLint location, GLint *params))
FN(int, glGetUniformLocation_impl_20, (GLuint program, const char *name))
//FN(void, glGetVertexAttribfv_impl_20, (GLuint index, GLenum pname, GLfloat *params))
//FN(void, glGetVertexAttribiv_impl_20, (GLuint index, GLenum pname, GLint *params))
//FN(void, glGetVertexAttribPointerv_impl_20, (GLuint index, GLenum pname, void **pointer))
FN(GLboolean, glIsProgram_impl_20, (GLuint program))
FN(GLboolean, glIsShader_impl_20, (GLuint shader))
FN(void, glLinkProgram_impl_20, (GLuint program))
FN(void, glPointSize_impl_20, (GLfloat size)) // S
FN(void, glUniform1i_impl_20, (GLint location, GLint x))
FN(void, glUniform2i_impl_20, (GLint location, GLint x, GLint y))
FN(void, glUniform3i_impl_20, (GLint location, GLint x, GLint y, GLint z))
FN(void, glUniform4i_impl_20, (GLint location, GLint x, GLint y, GLint z, GLint w))
FN(void, glUniform1f_impl_20, (GLint location, GLfloat x))
FN(void, glUniform2f_impl_20, (GLint location, GLfloat x, GLfloat y))
FN(void, glUniform3f_impl_20, (GLint location, GLfloat x, GLfloat y, GLfloat z))
FN(void, glUniform4f_impl_20, (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w))
FN(void, glUniform1iv_impl_20, (GLint location, GLsizei count, int size, const GLint *v))
FN(void, glUniform2iv_impl_20, (GLint location, GLsizei count, int size, const GLint *v))
FN(void, glUniform3iv_impl_20, (GLint location, GLsizei count, int size, const GLint *v))
FN(void, glUniform4iv_impl_20, (GLint location, GLsizei count, int size, const GLint *v))
FN(void, glUniform1fv_impl_20, (GLint location, GLsizei count, int size, const GLfloat *v))
FN(void, glUniform2fv_impl_20, (GLint location, GLsizei count, int size, const GLfloat *v))
FN(void, glUniform3fv_impl_20, (GLint location, GLsizei count, int size, const GLfloat *v))
FN(void, glUniform4fv_impl_20, (GLint location, GLsizei count, int size, const GLfloat *v))
FN(void, glUniformMatrix2fv_impl_20, (GLint location, GLsizei count, GLboolean transpose, int size, const GLfloat *value))
FN(void, glUniformMatrix3fv_impl_20, (GLint location, GLsizei count, GLboolean transpose, int size, const GLfloat *value))
FN(void, glUniformMatrix4fv_impl_20, (GLint location, GLsizei count, GLboolean transpose, int size, const GLfloat *value))
FN(void, glUseProgram_impl_20, (GLuint program)) // S
FN(void, glValidateProgram_impl_20, (GLuint program))
//FN(void, glVertexAttrib1f_impl_20, (GLuint indx, GLfloat x))
//FN(void, glVertexAttrib2f_impl_20, (GLuint indx, GLfloat x, GLfloat y))
//FN(void, glVertexAttrib3f_impl_20, (GLuint indx, GLfloat x, GLfloat y, GLfloat z))
//FN(void, glVertexAttrib4f_impl_20, (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w))
//FN(void, glVertexAttrib1fv_impl_20, (GLuint indx, const GLfloat *values))
//FN(void, glVertexAttrib2fv_impl_20, (GLuint indx, const GLfloat *values))
//FN(void, glVertexAttrib3fv_impl_20, (GLuint indx, const GLfloat *values))
//FN(void, glVertexAttrib4fv_impl_20, (GLuint indx, const GLfloat *values))
/* OES_shader_source */
FN(void, glCompileShader_impl_20, (GLuint shader))
FN(int, glGetShaderiv_impl_20, (GLuint shader, GLenum pname, GLint *params))
FN(void, glGetShaderInfoLog_impl_20, (GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog))
FN(void, glGetShaderSource_impl_20, (GLuint shader, GLsizei bufsize, GLsizei *length, char *source))
FN(void, glShaderSource_impl_20, (GLuint shader, GLsizei count, const char **string, const GLint *length))
//FN(void, glGetShaderPrecisionFormat_impl_20, (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision))
FN(void, glGetShaderPrecisionFormat_impl_20, (GLenum shadertype, GLenum precisiontype, GLint *result))
/*****************************************************************************************/
/* OES extension functions */
/*****************************************************************************************/
//gl 2.0 specific
//FN(void, glVertexAttribPointer_impl_20, (GLuint indx))
#if GL_OES_EGL_image
FN(void, glEGLImageTargetRenderbufferStorageOES_impl_20, (GLenum target, GLeglImageOES image))
#if EGL_BRCM_global_image
FN(void, glGlobalImageRenderbufferStorageOES_impl_20, (GLenum target, GLuint id_0, GLuint id_1))
#endif
#endif
#undef FN

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,164 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GLXX_CLIENT_H
#define GLXX_CLIENT_H
#include "interface/khronos/common/khrn_client.h"
#include "interface/khronos/common/khrn_client_platform.h"
#include "interface/khronos/common/khrn_client_cache.h"
#include "interface/khronos/egl/egl_client_context.h"
#include "interface/khronos/glxx/glxx_int_attrib.h"
#include "interface/khronos/glxx/glxx_int_config.h"
/*
Called just before a rendering command (i.e. anything which could modify
the draw surface) is executed
*/
typedef void (*GL_RENDER_CALLBACK_T)(void);
/*
Called just after rendering has been compeleted (i.e. flush or finish).
wait should be true for finish-like behaviour, false for flush-like
behaviour
*/
typedef void (*GL_FLUSH_CALLBACK_T)(bool wait);
/*
GL 1.1 and 2.0 client state structure
*/
typedef struct buffer_info {
GLuint id;
GLsizeiptr cached_size;
void * mapped_pointer;
GLsizeiptr mapped_size;
} GLXX_BUFFER_INFO_T;
typedef struct {
GLenum error;
/*
Open GL version
Invariants:
OPENGL_ES_11 or OPENGL_ES_20
*/
unsigned int type;
/*
alignments
used to work out how much data to send for glTexImage2D()
*/
struct {
GLint pack;
GLint unpack;
} alignment;
struct {
GLuint array;
GLuint element_array;
} bound_buffer;
GLXX_ATTRIB_T attrib[GLXX_CONFIG_MAX_VERTEX_ATTRIBS];
GL_RENDER_CALLBACK_T render_callback;
GL_FLUSH_CALLBACK_T flush_callback;
KHRN_CACHE_T cache;
//gl 1.1 specific
struct {
GLenum client;
GLenum server;
} active_texture;
//gl 2.0 specific
bool default_framebuffer; //render_callback only called if we're rendering to default framebuffer
KHRN_POINTER_MAP_T buffers;
} GLXX_CLIENT_STATE_T;
extern int gl11_client_state_init(GLXX_CLIENT_STATE_T *state);
extern int gl20_client_state_init(GLXX_CLIENT_STATE_T *state);
extern void glxx_client_state_free(GLXX_CLIENT_STATE_T *state);
#define GLXX_GET_CLIENT_STATE(thread) glxx_get_client_state(thread)
static INLINE GLXX_CLIENT_STATE_T *glxx_get_client_state(CLIENT_THREAD_STATE_T *thread)
{
EGL_CONTEXT_T *context = thread->opengl.context;
GLXX_CLIENT_STATE_T * state;
vcos_assert( context != NULL );
vcos_assert(context->type == OPENGL_ES_11 || context->type == OPENGL_ES_20);
state = (GLXX_CLIENT_STATE_T *)context->state;
vcos_assert(context->type == state->type);
return state;
}
#define GLXX_API_11 (1<<(OPENGL_ES_11))
#define GLXX_API_20 (1<<(OPENGL_ES_20))
#define GLXX_API_11_OR_20 (GLXX_API_11|GLXX_API_20)
static INLINE bool glxx_api_ok(uint32_t api, EGL_CONTEXT_TYPE_T type)
{
return !!(api & (1<<type));
}
#define IS_OPENGLES_11(thread) is_opengles_api(thread, GLXX_API_11)
#define IS_OPENGLES_20(thread) is_opengles_api(thread, GLXX_API_20)
#define IS_OPENGLES_11_OR_20(thread) is_opengles_api(thread, GLXX_API_11_OR_20)
#define IS_OPENGLES_API(thread, api) is_opengles_api(thread, api)
static INLINE bool is_opengles_api(CLIENT_THREAD_STATE_T *thread, uint32_t api)
{
EGL_CONTEXT_T *context = thread->opengl.context;
return context && glxx_api_ok(api, context->type);
}
extern void glxx_buffer_info_get(GLXX_CLIENT_STATE_T *state, GLenum target, GLXX_BUFFER_INFO_T* buffer);
extern void glxx_buffer_info_set(GLXX_CLIENT_STATE_T *state, GLenum target, GLXX_BUFFER_INFO_T* buffer);
extern void glxx_set_error(GLXX_CLIENT_STATE_T *state, GLenum error);
extern void glxx_set_error_api(uint32_t api, GLenum error);
/* Fake GL API calls */
void glintAttribPointer (uint32_t api, uint32_t indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr);
void glintAttrib (uint32_t api, uint32_t indx, float x, float y, float z, float w);
void glintColor(float red, float green, float blue, float alpha);
void glintAttribEnable(uint32_t api, uint32_t indx, bool enabled);
void *glintAttribGetPointer(uint32_t api, uint32_t indx);
#endif

View File

@@ -0,0 +1,143 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GLXX_INT_ATTRIB_H
#define GLXX_INT_ATTRIB_H
#include "interface/khronos/include/GLES/gl.h"
#include "interface/khronos/include/GLES2/gl2.h"
#include "interface/khronos/glxx/gl11_int_config.h"
#include "interface/khronos/glxx/glxx_int_config.h"
#include <stddef.h>
typedef struct {
GLboolean enabled;
GLint size;
GLenum type;
GLboolean normalized;
GLsizei stride;
const GLvoid *pointer;
GLuint buffer;
GLfloat value[4];
} GLXX_ATTRIB_T;
/* GL 1.1 specific For indexing into arrays of handles/pointers */
#define GL11_IX_COLOR 1//0
#define GL11_IX_NORMAL 2//1
#define GL11_IX_VERTEX 0//2
#define GL11_IX_TEXTURE_COORD 3
#define GL11_IX_POINT_SIZE 7
#define GL11_IX_MATRIX_WEIGHT 8
#define GL11_IX_MATRIX_INDEX 9
#define GL11_IX_MAX_ATTRIBS 10
/* Special values passed to glintAttrib etc. instead of indices */
#define GL11_IX_CLIENT_ACTIVE_TEXTURE 0x80000000
static INLINE void gl20_attrib_init(GLXX_ATTRIB_T *attrib)
{
uint32_t i;
for (i = 0; i < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; i++)
{
attrib[i].enabled = GL_FALSE;
attrib[i].size = 4;
attrib[i].type = GL_FLOAT;
attrib[i].normalized = GL_FALSE;
attrib[i].stride = 0;
attrib[i].pointer = NULL;
attrib[i].buffer = 0;
attrib[i].value[0] = 0.0f;
attrib[i].value[1] = 0.0f;
attrib[i].value[2] = 0.0f;
attrib[i].value[3] = 1.0f;
}
}
static INLINE void gl11_attrib_init(GLXX_ATTRIB_T *attrib)
{
int32_t i, indx;
gl20_attrib_init(attrib);
//vertex
attrib[GL11_IX_VERTEX].size = 4;
attrib[GL11_IX_VERTEX].normalized = GL_FALSE;
attrib[GL11_IX_VERTEX].value[0] = 0.0f;
attrib[GL11_IX_VERTEX].value[1] = 0.0f;
attrib[GL11_IX_VERTEX].value[2] = 0.0f;
attrib[GL11_IX_VERTEX].value[3] = 1.0f;
//color
attrib[GL11_IX_COLOR].size = 4;
attrib[GL11_IX_COLOR].normalized = GL_TRUE;
attrib[GL11_IX_COLOR].value[0] = 1.0f;
attrib[GL11_IX_COLOR].value[1] = 1.0f;
attrib[GL11_IX_COLOR].value[2] = 1.0f;
attrib[GL11_IX_COLOR].value[3] = 1.0f;
//normal
attrib[GL11_IX_NORMAL].size = 3;
attrib[GL11_IX_NORMAL].normalized = GL_TRUE;
attrib[GL11_IX_NORMAL].value[0] = 0.0f;
attrib[GL11_IX_NORMAL].value[1] = 0.0f;
attrib[GL11_IX_NORMAL].value[2] = 1.0f;
for (i = 0; i < GL11_CONFIG_MAX_TEXTURE_UNITS; i++) {
indx = GL11_IX_TEXTURE_COORD + i;
attrib[indx].size = 4;
attrib[indx].normalized = GL_FALSE;
attrib[indx].value[0] = 0.0f;
attrib[indx].value[1] = 0.0f;
attrib[indx].value[2] = 0.0f;
attrib[indx].value[3] = 1.0f;
}
//point size
attrib[GL11_IX_POINT_SIZE].size = 1;
attrib[GL11_IX_POINT_SIZE].normalized = GL_FALSE;
attrib[GL11_IX_POINT_SIZE].value[0] = 1.0f;
}
typedef struct
{
uint32_t cache_offset; /* How far into the cache this attrib starts */
uint32_t has_interlock; /* (Boolean) Whether there is an interlock immediately before this attrib. */
} GLXX_CACHE_INFO_ENTRY_T;
typedef struct
{
uint32_t send_any; /* True if we're sending any vertices. If false, remainder of structure is invalid. */
GLXX_CACHE_INFO_ENTRY_T entries[GLXX_CONFIG_MAX_VERTEX_ATTRIBS];
} GLXX_CACHE_INFO_T;
#endif

Some files were not shown because too many files have changed in this diff Show More