Home | History | Annotate | Download | only in EGL
      1 /*
      2  ** Copyright 2007, The Android Open Source Project
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 
     17 #include "egl_object.h"
     18 
     19 #include <sstream>
     20 
     21 
     22 // ----------------------------------------------------------------------------
     23 namespace android {
     24 // ----------------------------------------------------------------------------
     25 
     26 egl_object_t::egl_object_t(egl_display_t* disp) :
     27     display(disp), count(1) {
     28     // NOTE: this does an implicit incRef
     29     display->addObject(this);
     30 }
     31 
     32 egl_object_t::~egl_object_t() {
     33 }
     34 
     35 void egl_object_t::terminate() {
     36     // this marks the object as "terminated"
     37     display->removeObject(this);
     38     if (decRef() == 1) {
     39         // shouldn't happen because this is called from LocalRef
     40         ALOGE("egl_object_t::terminate() removed the last reference!");
     41     }
     42 }
     43 
     44 void egl_object_t::destroy() {
     45     if (decRef() == 1) {
     46         delete this;
     47     }
     48 }
     49 
     50 bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
     51     // used by LocalRef, this does an incRef() atomically with
     52     // checking that the object is valid.
     53     return display->getObject(object);
     54 }
     55 
     56 // ----------------------------------------------------------------------------
     57 
     58 egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win,
     59                              EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx)
     60       : egl_object_t(dpy),
     61         surface(surface),
     62         config(config),
     63         win(win),
     64         cnx(cnx),
     65         connected(true),
     66         colorSpace(colorSpace),
     67         egl_smpte2086_dirty(false),
     68         egl_cta861_3_dirty(false) {
     69     egl_smpte2086_metadata.displayPrimaryRed = { EGL_DONT_CARE, EGL_DONT_CARE };
     70     egl_smpte2086_metadata.displayPrimaryGreen = { EGL_DONT_CARE, EGL_DONT_CARE };
     71     egl_smpte2086_metadata.displayPrimaryBlue = { EGL_DONT_CARE, EGL_DONT_CARE };
     72     egl_smpte2086_metadata.whitePoint = { EGL_DONT_CARE, EGL_DONT_CARE };
     73     egl_smpte2086_metadata.maxLuminance = EGL_DONT_CARE;
     74     egl_smpte2086_metadata.minLuminance = EGL_DONT_CARE;
     75     egl_cta861_3_metadata.maxFrameAverageLightLevel = EGL_DONT_CARE;
     76     egl_cta861_3_metadata.maxContentLightLevel = EGL_DONT_CARE;
     77 
     78     if (win) {
     79         win->incStrong(this);
     80     }
     81 }
     82 
     83 egl_surface_t::~egl_surface_t() {
     84     if (win != NULL) {
     85         disconnect();
     86         win->decStrong(this);
     87     }
     88 }
     89 
     90 void egl_surface_t::disconnect() {
     91     if (win != NULL && connected) {
     92         native_window_set_buffers_format(win, 0);
     93         if (native_window_api_disconnect(win, NATIVE_WINDOW_API_EGL)) {
     94             ALOGW("EGLNativeWindowType %p disconnect failed", win);
     95         }
     96         connected = false;
     97     }
     98 }
     99 
    100 EGLBoolean egl_surface_t::setSmpte2086Attribute(EGLint attribute, EGLint value) {
    101     switch (attribute) {
    102         case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
    103             egl_smpte2086_metadata.displayPrimaryRed.x = value;
    104             egl_smpte2086_dirty = true;
    105             return EGL_TRUE;
    106         case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
    107             egl_smpte2086_metadata.displayPrimaryRed.y = value;
    108             egl_smpte2086_dirty = true;
    109             return EGL_TRUE;
    110         case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
    111             egl_smpte2086_metadata.displayPrimaryGreen.x = value;
    112             egl_smpte2086_dirty = true;
    113             return EGL_TRUE;
    114         case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
    115             egl_smpte2086_metadata.displayPrimaryGreen.y = value;
    116             egl_smpte2086_dirty = true;
    117             return EGL_TRUE;
    118         case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
    119             egl_smpte2086_metadata.displayPrimaryBlue.x = value;
    120             egl_smpte2086_dirty = true;
    121             return EGL_TRUE;
    122         case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
    123             egl_smpte2086_metadata.displayPrimaryBlue.y = value;
    124             egl_smpte2086_dirty = true;
    125             return EGL_TRUE;
    126         case EGL_SMPTE2086_WHITE_POINT_X_EXT:
    127             egl_smpte2086_metadata.whitePoint.x = value;
    128             egl_smpte2086_dirty = true;
    129             return EGL_TRUE;
    130         case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
    131             egl_smpte2086_metadata.whitePoint.y = value;
    132             egl_smpte2086_dirty = true;
    133             return EGL_TRUE;
    134         case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
    135             egl_smpte2086_metadata.maxLuminance = value;
    136             egl_smpte2086_dirty = true;
    137             return EGL_TRUE;
    138         case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
    139             egl_smpte2086_metadata.minLuminance = value;
    140             egl_smpte2086_dirty = true;
    141             return EGL_TRUE;
    142     }
    143     return EGL_FALSE;
    144 }
    145 
    146 EGLBoolean egl_surface_t::setCta8613Attribute(EGLint attribute, EGLint value) {
    147     switch (attribute) {
    148         case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
    149             egl_cta861_3_metadata.maxContentLightLevel = value;
    150             egl_cta861_3_dirty = true;
    151             return EGL_TRUE;
    152         case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
    153             egl_cta861_3_metadata.maxFrameAverageLightLevel = value;
    154             egl_cta861_3_dirty = true;
    155             return EGL_TRUE;
    156     }
    157     return EGL_FALSE;
    158 }
    159 
    160 EGLBoolean egl_surface_t::getSmpte2086Metadata(android_smpte2086_metadata& metadata) const {
    161     if (!egl_smpte2086_dirty) return EGL_FALSE;
    162     if (egl_smpte2086_metadata.displayPrimaryRed.x == EGL_DONT_CARE ||
    163         egl_smpte2086_metadata.displayPrimaryRed.y == EGL_DONT_CARE ||
    164         egl_smpte2086_metadata.displayPrimaryGreen.x == EGL_DONT_CARE ||
    165         egl_smpte2086_metadata.displayPrimaryGreen.y == EGL_DONT_CARE ||
    166         egl_smpte2086_metadata.displayPrimaryBlue.x == EGL_DONT_CARE ||
    167         egl_smpte2086_metadata.displayPrimaryBlue.y == EGL_DONT_CARE ||
    168         egl_smpte2086_metadata.whitePoint.x == EGL_DONT_CARE ||
    169         egl_smpte2086_metadata.whitePoint.y == EGL_DONT_CARE ||
    170         egl_smpte2086_metadata.maxLuminance == EGL_DONT_CARE ||
    171         egl_smpte2086_metadata.minLuminance == EGL_DONT_CARE) {
    172         ALOGW("egl_surface_t: incomplete SMPTE 2086 metadata!");
    173         return EGL_FALSE;
    174     }
    175 
    176     metadata.displayPrimaryRed.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.x) / EGL_METADATA_SCALING_EXT;
    177     metadata.displayPrimaryRed.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.y) / EGL_METADATA_SCALING_EXT;
    178     metadata.displayPrimaryGreen.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.x) / EGL_METADATA_SCALING_EXT;
    179     metadata.displayPrimaryGreen.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.y) / EGL_METADATA_SCALING_EXT;
    180     metadata.displayPrimaryBlue.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.x) / EGL_METADATA_SCALING_EXT;
    181     metadata.displayPrimaryBlue.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.y) / EGL_METADATA_SCALING_EXT;
    182     metadata.whitePoint.x = static_cast<float>(egl_smpte2086_metadata.whitePoint.x) / EGL_METADATA_SCALING_EXT;
    183     metadata.whitePoint.y = static_cast<float>(egl_smpte2086_metadata.whitePoint.y) / EGL_METADATA_SCALING_EXT;
    184     metadata.maxLuminance = static_cast<float>(egl_smpte2086_metadata.maxLuminance) / EGL_METADATA_SCALING_EXT;
    185     metadata.minLuminance = static_cast<float>(egl_smpte2086_metadata.minLuminance) / EGL_METADATA_SCALING_EXT;
    186 
    187     return EGL_TRUE;
    188 }
    189 
    190 EGLBoolean egl_surface_t::getCta8613Metadata(android_cta861_3_metadata& metadata) const {
    191     if (!egl_cta861_3_dirty) return EGL_FALSE;
    192 
    193     if (egl_cta861_3_metadata.maxContentLightLevel == EGL_DONT_CARE ||
    194         egl_cta861_3_metadata.maxFrameAverageLightLevel == EGL_DONT_CARE) {
    195         ALOGW("egl_surface_t: incomplete CTA861.3 metadata!");
    196         return EGL_FALSE;
    197     }
    198 
    199     metadata.maxContentLightLevel = static_cast<float>(egl_cta861_3_metadata.maxContentLightLevel) / EGL_METADATA_SCALING_EXT;
    200     metadata.maxFrameAverageLightLevel = static_cast<float>(egl_cta861_3_metadata.maxFrameAverageLightLevel) / EGL_METADATA_SCALING_EXT;
    201 
    202     return EGL_TRUE;
    203 }
    204 
    205 
    206 EGLBoolean egl_surface_t::getColorSpaceAttribute(EGLint attribute, EGLint* value) const {
    207     if (attribute == EGL_GL_COLORSPACE_KHR) {
    208         *value = colorSpace;
    209         return EGL_TRUE;
    210     }
    211     return EGL_FALSE;
    212 }
    213 
    214 EGLBoolean egl_surface_t::getSmpte2086Attribute(EGLint attribute, EGLint *value) const {
    215     switch (attribute) {
    216         case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
    217             *value = egl_smpte2086_metadata.displayPrimaryRed.x;
    218             return EGL_TRUE;
    219             break;
    220         case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
    221             *value = egl_smpte2086_metadata.displayPrimaryRed.y;
    222             return EGL_TRUE;
    223             break;
    224         case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
    225             *value = egl_smpte2086_metadata.displayPrimaryGreen.x;
    226             return EGL_TRUE;
    227             break;
    228         case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
    229             *value = egl_smpte2086_metadata.displayPrimaryGreen.y;
    230             return EGL_TRUE;
    231             break;
    232         case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
    233             *value = egl_smpte2086_metadata.displayPrimaryBlue.x;
    234             return EGL_TRUE;
    235             break;
    236         case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
    237             *value = egl_smpte2086_metadata.displayPrimaryBlue.y;
    238             return EGL_TRUE;
    239             break;
    240         case EGL_SMPTE2086_WHITE_POINT_X_EXT:
    241             *value = egl_smpte2086_metadata.whitePoint.x;
    242             return EGL_TRUE;
    243             break;
    244         case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
    245             *value = egl_smpte2086_metadata.whitePoint.y;
    246             return EGL_TRUE;
    247             break;
    248         case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
    249             *value = egl_smpte2086_metadata.maxLuminance;
    250             return EGL_TRUE;
    251             break;
    252         case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
    253             *value = egl_smpte2086_metadata.minLuminance;
    254             return EGL_TRUE;
    255             break;
    256     }
    257     return EGL_FALSE;
    258 }
    259 
    260 EGLBoolean egl_surface_t::getCta8613Attribute(EGLint attribute, EGLint *value) const {
    261     switch (attribute) {
    262         case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
    263             *value = egl_cta861_3_metadata.maxContentLightLevel;
    264             return EGL_TRUE;
    265             break;
    266         case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
    267             *value = egl_cta861_3_metadata.maxFrameAverageLightLevel;
    268             return EGL_TRUE;
    269             break;
    270     }
    271     return EGL_FALSE;
    272 }
    273 
    274 void egl_surface_t::terminate() {
    275     disconnect();
    276     egl_object_t::terminate();
    277 }
    278 
    279 // ----------------------------------------------------------------------------
    280 
    281 egl_context_t::egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
    282         egl_connection_t const* cnx, int version) :
    283     egl_object_t(get_display_nowake(dpy)), dpy(dpy), context(context),
    284             config(config), read(0), draw(0), cnx(cnx), version(version) {
    285 }
    286 
    287 void egl_context_t::onLooseCurrent() {
    288     read = NULL;
    289     draw = NULL;
    290 }
    291 
    292 void egl_context_t::onMakeCurrent(EGLSurface draw, EGLSurface read) {
    293     this->read = read;
    294     this->draw = draw;
    295 
    296     /*
    297      * Here we cache the GL_EXTENSIONS string for this context and we
    298      * add the extensions always handled by the wrapper
    299      */
    300 
    301     if (gl_extensions.empty()) {
    302         // call the implementation's glGetString(GL_EXTENSIONS)
    303         const char* exts = (const char *)gEGLImpl.hooks[version]->gl.glGetString(GL_EXTENSIONS);
    304 
    305         // If this context is sharing with another context, and the other context was reset
    306         // e.g. due to robustness failure, this context might also be reset and glGetString can
    307         // return NULL.
    308         if (exts) {
    309             gl_extensions = exts;
    310             if (gl_extensions.find("GL_EXT_debug_marker") == std::string::npos) {
    311                 gl_extensions.insert(0, "GL_EXT_debug_marker ");
    312             }
    313 
    314             // tokenize the supported extensions for the glGetStringi() wrapper
    315             std::stringstream ss;
    316             std::string str;
    317             ss << gl_extensions;
    318             while (ss >> str) {
    319                 tokenized_gl_extensions.push_back(str);
    320             }
    321         }
    322     }
    323 }
    324 
    325 // ----------------------------------------------------------------------------
    326 }; // namespace android
    327 // ----------------------------------------------------------------------------
    328