- Main Page
- Modules
- Namespaces
- Classes
- Files

- Search for |

- File List
- File Members

# samples/common/classes/NvEglRenderer.cpp

Go to the documentation of this file.

    00001 /*
    00002  * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
    00003  *
    00004  * Redistribution and use in source and binary forms, with or without
    00005  * modification, are permitted provided that the following conditions
    00006  * are met:
    00007  *  * Redistributions of source code must retain the above copyright
    00008  *    notice, this list of conditions and the following disclaimer.
    00009  *  * Redistributions in binary form must reproduce the above copyright
    00010  *    notice, this list of conditions and the following disclaimer in the
    00011  *    documentation and/or other materials provided with the distribution.
    00012  *  * Neither the name of NVIDIA CORPORATION nor the names of its
    00013  *    contributors may be used to endorse or promote products derived
    00014  *    from this software without specific prior written permission.
    00015  *
    00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
    00017  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    00019  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    00020  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    00021  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    00022  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    00023  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    00024  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    00026  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00027  */
    00028
    00029 #include "NvEglRenderer.h"
    00030 #include "NvLogging.h"
    00031 #include "nvbuf_utils.h"
    00032
    00033 #include <cstring>
    00034 #include <sys/time.h>
    00035
    00036 #define CAT_NAME "EglRenderer"
    00037
    00038 #define ERROR_GOTO_FAIL(val, string) \
    00039     do { \
    00040         if (val) {\
    00041             CAT_DEBUG_MSG(string); \
    00042             goto fail; \
    00043         } \
    00044     } while (0)
    00045
    00046 PFNEGLCREATEIMAGEKHRPROC                NvEglRenderer::eglCreateImageKHR;
    00047 PFNEGLDESTROYIMAGEKHRPROC               NvEglRenderer::eglDestroyImageKHR;
    00048 PFNEGLCREATESYNCKHRPROC                 NvEglRenderer::eglCreateSyncKHR;
    00049 PFNEGLDESTROYSYNCKHRPROC                NvEglRenderer::eglDestroySyncKHR;
    00050 PFNEGLCLIENTWAITSYNCKHRPROC             NvEglRenderer::eglClientWaitSyncKHR;
    00051 PFNEGLGETSYNCATTRIBKHRPROC              NvEglRenderer::eglGetSyncAttribKHR;
    00052 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC     NvEglRenderer::glEGLImageTargetTexture2DOES;
    00053
    00054 using namespace std;
    00055
    00056 NvEglRenderer::NvEglRenderer(const char *name, uint32_t width, uint32_t height,
    00057         uint32_t x_offset, uint32_t y_offset)
    00058         :NvElement(name, valid_fields)
    00059 {
    00060     int depth;
    00061     int screen_num;
    00062     XSetWindowAttributes window_attributes;
    00063     x_window = 0;
    00064     x_display = NULL;
    00065
    00066     texture_id = 0;
    00067     gc = NULL;
    00068     fontinfo = NULL;
    00069
    00070     egl_surface = EGL_NO_SURFACE;
    00071     egl_context = EGL_NO_CONTEXT;
    00072     egl_display = EGL_NO_DISPLAY;
    00073     egl_config = NULL;
    00074
    00075     memset(&last_render_time, 0, sizeof(last_render_time));
    00076     stop_thread = false;
    00077     render_thread = 0;
    00078
    00079     memset(overlay_str, 0, sizeof(overlay_str));
    00080     overlay_str_x_offset = 0;
    00081     overlay_str_y_offset = 0;
    00082
    00083     pthread_mutex_init(&render_lock, NULL);
    00084     pthread_cond_init(&render_cond, NULL);
    00085
    00086     setFPS(30);
    00087
    00088     if (initEgl() < 0)
    00089     {
    00090         COMP_ERROR_MSG("Error getting EGL function addresses");
    00091         goto error;
    00092     }
    00093
    00094     x_display = XOpenDisplay(NULL);
    00095     if (NULL == x_display)
    00096     {
    00097         COMP_ERROR_MSG("Error in opening display");
    00098         goto error;
    00099     }
    00100
    00101     screen_num = DefaultScreen(x_display);
    00102     if (!width || !height)
    00103     {
    00104         width = DisplayWidth(x_display, screen_num);
    00105         height = DisplayHeight(x_display, screen_num);
    00106         x_offset = 0;
    00107         y_offset = 0;
    00108     }
    00109     COMP_ERROR_MSG("Setting Screen width " << width << " height " << height);
    00110
    00111     COMP_DEBUG_MSG("Display opened successfully " << (size_t) x_display);
    00112
    00113     depth = DefaultDepth(x_display, DefaultScreen(x_display));
    00114
    00115     window_attributes.background_pixel =
    00116         BlackPixel(x_display, DefaultScreen(x_display));
    00117
    00118     window_attributes.override_redirect = 1;
    00119
    00120     x_window = XCreateWindow(x_display,
    00121                              DefaultRootWindow(x_display), x_offset,
    00122                              y_offset, width, height,
    00123                              0,
    00124                              depth, CopyFromParent,
    00125                              CopyFromParent,
    00126                              (CWBackPixel | CWOverrideRedirect),
    00127                              &window_attributes);
    00128
    00129     XSelectInput(x_display, (int32_t) x_window, ExposureMask);
    00130     XMapWindow(x_display, (int32_t) x_window);
    00131     gc = XCreateGC(x_display, x_window, 0, NULL);
    00132
    00133     XSetForeground(x_display, gc,
    00134                 WhitePixel(x_display, DefaultScreen(x_display)) );
    00135     fontinfo = XLoadQueryFont(x_display, "9x15bold");
    00136
    00137     pthread_mutex_lock(&render_lock);
    00138     pthread_create(&render_thread, NULL, renderThread, this);
    00139     pthread_cond_wait(&render_cond, &render_lock);
    00140     pthread_mutex_unlock(&render_lock);
    00141
    00142     if(isInError())
    00143     {
    00144         pthread_join(render_thread, NULL);
    00145         goto error;
    00146     }
    00147
    00148     COMP_DEBUG_MSG("Renderer started successfully")
    00149     return;
    00150
    00151 error:
    00152     COMP_ERROR_MSG("Got ERROR closing display");
    00153     is_in_error = 1;
    00154 }
    00155
    00156 int
    00157 NvEglRenderer::getDisplayResolution(uint32_t &width, uint32_t &height)
    00158 {
    00159     int screen_num;
    00160     Display * x_display = XOpenDisplay(NULL);
    00161     if (NULL == x_display)
    00162     {
    00163         return  -1;
    00164     }
    00165
    00166     screen_num = DefaultScreen(x_display);
    00167     width = DisplayWidth(x_display, screen_num);
    00168     height = DisplayHeight(x_display, screen_num);
    00169
    00170     XCloseDisplay(x_display);
    00171     x_display = NULL;
    00172
    00173     return 0;
    00174 }
    00175
    00176 void *
    00177 NvEglRenderer::renderThread(void *arg)
    00178 {
    00179     EGLBoolean egl_status;
    00180     NvEglRenderer *renderer = (NvEglRenderer *) arg;
    00181     const char *comp_name = renderer->comp_name;
    00182
    00183     static EGLint rgba8888[] = {
    00184         EGL_RED_SIZE, 8,
    00185         EGL_GREEN_SIZE, 8,
    00186         EGL_BLUE_SIZE, 8,
    00187         EGL_ALPHA_SIZE, 8,
    00188         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    00189         EGL_NONE,
    00190     };
    00191     int num_configs = 0;
    00192     EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
    00193     renderer->egl_display = eglGetDisplay(renderer->x_display);
    00194     if (EGL_NO_DISPLAY == renderer->egl_display)
    00195     {
    00196         COMP_ERROR_MSG("Unable to get egl display");
    00197         goto error;
    00198     }
    00199     COMP_DEBUG_MSG("Egl Got display " << (size_t) renderer->egl_display);
    00200
    00201     egl_status = eglInitialize(renderer->egl_display, 0, 0);
    00202     if (!egl_status)
    00203     {
    00204         COMP_ERROR_MSG("Unable to initialize egl library");
    00205         goto error;
    00206     }
    00207
    00208     egl_status =
    00209         eglChooseConfig(renderer->egl_display, rgba8888,
    00210                             &renderer->egl_config, 1, &num_configs);
    00211     if (!egl_status)
    00212     {
    00213         COMP_ERROR_MSG("Error at eglChooseConfig");
    00214         goto error;
    00215     }
    00216     COMP_DEBUG_MSG("Got numconfigs as " << num_configs);
    00217
    00218     renderer->egl_context =
    00219         eglCreateContext(renderer->egl_display, renderer->egl_config,
    00220                             EGL_NO_CONTEXT, context_attribs);
    00221     if (eglGetError() != EGL_SUCCESS)
    00222     {
    00223         COMP_ERROR_MSG("Got Error in eglCreateContext " << eglGetError());
    00224         goto error;
    00225     }
    00226     renderer->egl_surface =
    00227         eglCreateWindowSurface(renderer->egl_display, renderer->egl_config,
    00228                 (EGLNativeWindowType) renderer->x_window, NULL);
    00229     if (renderer->egl_surface == EGL_NO_SURFACE)
    00230     {
    00231         COMP_ERROR_MSG("Error in creating egl surface " << eglGetError());
    00232         goto error;
    00233     }
    00234
    00235     eglMakeCurrent(renderer->egl_display, renderer->egl_surface,
    00236                     renderer->egl_surface, renderer->egl_context);
    00237     if (eglGetError() != EGL_SUCCESS)
    00238     {
    00239         COMP_ERROR_MSG("Error in eglMakeCurrent " << eglGetError());
    00240         goto error;
    00241     }
    00242
    00243     if (renderer->InitializeShaders() < 0)
    00244     {
    00245         COMP_ERROR_MSG("Error while initializing shaders");
    00246         goto error;
    00247     }
    00248
    00249     renderer->create_texture();
    00250
    00251     pthread_mutex_lock(&renderer->render_lock);
    00252     pthread_cond_broadcast(&renderer->render_cond);
    00253     COMP_DEBUG_MSG("Starting render thread");
    00254
    00255     while (!renderer->isInError() && !renderer->stop_thread)
    00256     {
    00257         pthread_cond_wait(&renderer->render_cond, &renderer->render_lock);
    00258         pthread_mutex_unlock(&renderer->render_lock);
    00259
    00260         if(renderer->stop_thread)
    00261         {
    00262             pthread_mutex_lock(&renderer->render_lock);
    00263             break;
    00264         }
    00265
    00266         renderer->renderInternal();
    00267         COMP_DEBUG_MSG("Rendered fd=" << renderer->render_fd);
    00268
    00269         pthread_mutex_lock(&renderer->render_lock);
    00270         pthread_cond_broadcast(&renderer->render_cond);
    00271     }
    00272     pthread_mutex_unlock(&renderer->render_lock);
    00273     COMP_DEBUG_MSG("Stopped render thread");
    00274
    00275 finish:
    00276     if (renderer->texture_id)
    00277     {
    00278         glDeleteTextures(1, &renderer->texture_id);
    00279     }
    00280
    00281     if (renderer->egl_display != EGL_NO_DISPLAY)
    00282     {
    00283         eglMakeCurrent(renderer->egl_display, EGL_NO_SURFACE,
    00284                 EGL_NO_SURFACE, EGL_NO_CONTEXT);
    00285     }
    00286
    00287     if (renderer->egl_surface != EGL_NO_SURFACE)
    00288     {
    00289         egl_status = eglDestroySurface(renderer->egl_display,
    00290                 renderer->egl_surface);
    00291         if (egl_status == EGL_FALSE)
    00292         {
    00293             COMP_ERROR_MSG("EGL surface destruction failed");
    00294         }
    00295     }
    00296
    00297     if (renderer->egl_context != EGL_NO_CONTEXT)
    00298     {
    00299         egl_status = eglDestroyContext(renderer->egl_display,
    00300                 renderer->egl_context);
    00301         if (egl_status == EGL_FALSE)
    00302         {
    00303             COMP_ERROR_MSG("EGL context destruction failed");
    00304         }
    00305     }
    00306
    00307     if (renderer->egl_display != EGL_NO_DISPLAY)
    00308     {
    00309         eglReleaseThread();
    00310         eglTerminate(renderer->egl_display);
    00311     }
    00312
    00313     pthread_mutex_lock(&renderer->render_lock);
    00314     pthread_cond_broadcast(&renderer->render_cond);
    00315     pthread_mutex_unlock(&renderer->render_lock);
    00316     return NULL;
    00317
    00318 error:
    00319     renderer->is_in_error = 1;
    00320     goto finish;
    00321 }
    00322
    00323 NvEglRenderer::~NvEglRenderer()
    00324 {
    00325     stop_thread = true;
    00326
    00327     pthread_mutex_lock(&render_lock);
    00328     pthread_cond_broadcast(&render_cond);
    00329     pthread_mutex_unlock(&render_lock);
    00330
    00331     pthread_join(render_thread, NULL);
    00332
    00333     pthread_mutex_destroy(&render_lock);
    00334     pthread_cond_destroy(&render_cond);
    00335
    00336     if (fontinfo)
    00337     {
    00338         XFreeFont(x_display, fontinfo);
    00339     }
    00340
    00341     if (gc)
    00342     {
    00343         XFreeGC(x_display, gc);
    00344     }
    00345
    00346     if (x_window)
    00347     {
    00348         XUnmapWindow(x_display, (int32_t) x_window);
    00349         XFlush(x_display);
    00350         XDestroyWindow(x_display, (int32_t) x_window);
    00351     }
    00352     if (x_display)
    00353     {
    00354         XCloseDisplay(x_display);
    00355     }
    00356 }
    00357
    00358 int
    00359 NvEglRenderer::render(int fd)
    00360 {
    00361     this->render_fd = fd;
    00362     pthread_mutex_lock(&render_lock);
    00363     pthread_cond_broadcast(&render_cond);
    00364     COMP_DEBUG_MSG("Rendering fd=" << fd);
    00365     pthread_cond_wait(&render_cond, &render_lock);
    00366     pthread_mutex_unlock(&render_lock);
    00367     return 0;
    00368 }
    00369
    00370 int
    00371 NvEglRenderer::renderInternal()
    00372 {
    00373     EGLImageKHR hEglImage;
    00374     bool frame_is_late = false;
    00375
    00376     EGLSyncKHR egl_sync;
    00377     int iErr;
    00378     hEglImage = NvEGLImageFromFd(egl_display, render_fd);
    00379     if (!hEglImage)
    00380     {
    00381         COMP_ERROR_MSG("Could not get EglImage from fd. Not rendering");
    00382         return -1;
    00383     }
    00384
    00385     glActiveTexture(GL_TEXTURE0);
    00386     glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
    00387     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, hEglImage);
    00388     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    00389
    00390     iErr = glGetError();
    00391     if (iErr != GL_NO_ERROR)
    00392     {
    00393         COMP_ERROR_MSG("glDrawArrays arrays failed:" << iErr);
    00394         return -1;
    00395     }
    00396     egl_sync = eglCreateSyncKHR(egl_display, EGL_SYNC_FENCE_KHR, NULL);
    00397     if (egl_sync == EGL_NO_SYNC_KHR)
    00398     {
    00399         COMP_ERROR_MSG("eglCreateSyncKHR() failed");
    00400         return -1;
    00401     }
    00402     if (last_render_time.tv_sec != 0)
    00403     {
    00404         pthread_mutex_lock(&render_lock);
    00405         last_render_time.tv_sec += render_time_sec;
    00406         last_render_time.tv_nsec += render_time_nsec;
    00407         last_render_time.tv_sec += last_render_time.tv_nsec / 1000000000UL;
    00408         last_render_time.tv_nsec %= 1000000000UL;
    00409
    00410         if (isProfilingEnabled())
    00411         {
    00412             struct timeval cur_time;
    00413             gettimeofday(&cur_time, NULL);
    00414             if ((cur_time.tv_sec * 1000000.0 + cur_time.tv_usec) >
    00415                     (last_render_time.tv_sec * 1000000.0 +
    00416                      last_render_time.tv_nsec / 1000.0))
    00417             {
    00418                 frame_is_late = true;
    00419             }
    00420         }
    00421
    00422         pthread_cond_timedwait(&render_cond, &render_lock,
    00423                 &last_render_time);
    00424
    00425         pthread_mutex_unlock(&render_lock);
    00426     }
    00427     else
    00428     {
    00429         struct timeval now;
    00430
    00431         gettimeofday(&now, NULL);
    00432         last_render_time.tv_sec = now.tv_sec;
    00433         last_render_time.tv_nsec = now.tv_usec * 1000L;
    00434     }
    00435     eglSwapBuffers(egl_display, egl_surface);
    00436     if (eglGetError() != EGL_SUCCESS)
    00437     {
    00438         COMP_ERROR_MSG("Got Error in eglSwapBuffers " << eglGetError());
    00439         return -1;
    00440     }
    00441     if (eglClientWaitSyncKHR (egl_display, egl_sync,
    00442                 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR) == EGL_FALSE)
    00443     {
    00444         COMP_ERROR_MSG("eglClientWaitSyncKHR failed!");
    00445     }
    00446
    00447     if (eglDestroySyncKHR(egl_display, egl_sync) != EGL_TRUE)
    00448     {
    00449         COMP_ERROR_MSG("eglDestroySyncKHR failed!");
    00450     }
    00451     NvDestroyEGLImage(egl_display, hEglImage);
    00452
    00453     if (strlen(overlay_str) != 0)
    00454     {
    00455         XSetForeground(x_display, gc,
    00456                         BlackPixel(x_display, DefaultScreen(x_display)));
    00457         XSetFont(x_display, gc, fontinfo->fid);
    00458         XDrawString(x_display, x_window, gc, overlay_str_x_offset,
    00459                     overlay_str_y_offset, overlay_str, strlen(overlay_str));
    00460     }
    00461
    00462     profiler.finishProcessing(0, frame_is_late);
    00463
    00464     return 0;
    00465 }
    00466
    00467 int
    00468 NvEglRenderer::setOverlayText(char *str, uint32_t x, uint32_t y)
    00469 {
    00470     strncpy(overlay_str, str, sizeof(overlay_str));
    00471     overlay_str[sizeof(overlay_str) - 1] = '\0';
    00472
    00473     overlay_str_x_offset = x;
    00474     overlay_str_y_offset = y;
    00475
    00476     return 0;
    00477 }
    00478
    00479 int
    00480 NvEglRenderer::setFPS(float fps)
    00481 {
    00482     uint64_t render_time_usec;
    00483
    00484     if (fps == 0)
    00485     {
    00486         COMP_WARN_MSG("Fps 0 is not allowed. Not changing fps");
    00487         return -1;
    00488     }
    00489     pthread_mutex_lock(&render_lock);
    00490     this->fps = fps;
    00491
    00492     render_time_usec = 1000000L / fps;
    00493     render_time_sec = render_time_usec / 1000000;
    00494     render_time_nsec = (render_time_usec % 1000000) * 1000L;
    00495     pthread_mutex_unlock(&render_lock);
    00496     return 0;
    00497 }
    00498
    00499 NvEglRenderer *
    00500 NvEglRenderer::createEglRenderer(const char *name, uint32_t width,
    00501                                uint32_t height, uint32_t x_offset,
    00502                                uint32_t y_offset)
    00503 {
    00504     NvEglRenderer* renderer = new NvEglRenderer(name, width, height,
    00505                                     x_offset, y_offset);
    00506     if (renderer->isInError())
    00507     {
    00508         delete renderer;
    00509         return NULL;
    00510     }
    00511     return renderer;
    00512 }
    00513
    00514 int
    00515 NvEglRenderer::initEgl()
    00516 {
    00517     eglCreateImageKHR =
    00518         (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
    00519     ERROR_GOTO_FAIL(!eglCreateImageKHR,
    00520                     "ERROR getting proc addr of eglCreateImageKHR\n");
    00521
    00522     eglDestroyImageKHR =
    00523         (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
    00524     ERROR_GOTO_FAIL(!eglDestroyImageKHR,
    00525                     "ERROR getting proc addr of eglDestroyImageKHR\n");
    00526
    00527     eglCreateSyncKHR =
    00528         (PFNEGLCREATESYNCKHRPROC) eglGetProcAddress("eglCreateSyncKHR");
    00529     ERROR_GOTO_FAIL(!eglCreateSyncKHR,
    00530                     "ERROR getting proc addr of eglCreateSyncKHR\n");
    00531
    00532     eglDestroySyncKHR =
    00533         (PFNEGLDESTROYSYNCKHRPROC) eglGetProcAddress("eglDestroySyncKHR");
    00534     ERROR_GOTO_FAIL(!eglDestroySyncKHR,
    00535                     "ERROR getting proc addr of eglDestroySyncKHR\n");
    00536
    00537     eglClientWaitSyncKHR =
    00538         (PFNEGLCLIENTWAITSYNCKHRPROC) eglGetProcAddress("eglClientWaitSyncKHR");
    00539     ERROR_GOTO_FAIL(!eglClientWaitSyncKHR,
    00540                     "ERROR getting proc addr of eglClientWaitSyncKHR\n");
    00541
    00542     eglGetSyncAttribKHR =
    00543         (PFNEGLGETSYNCATTRIBKHRPROC) eglGetProcAddress("eglGetSyncAttribKHR");
    00544     ERROR_GOTO_FAIL(!eglGetSyncAttribKHR,
    00545                     "ERROR getting proc addr of eglGetSyncAttribKHR\n");
    00546
    00547     glEGLImageTargetTexture2DOES =
    00548         (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
    00549         eglGetProcAddress("glEGLImageTargetTexture2DOES");
    00550     ERROR_GOTO_FAIL(!glEGLImageTargetTexture2DOES,
    00551                     "ERROR getting proc addr of glEGLImageTargetTexture2DOES\n");
    00552
    00553     return 0;
    00554
    00555 fail:
    00556     return -1;
    00557 }
    00558
    00559 void
    00560 NvEglRenderer::CreateShader(GLuint program, GLenum type, const char *source,
    00561         int size)
    00562 {
    00563
    00564     char log[4096];
    00565     int result = GL_FALSE;
    00566
    00567     GLuint shader = glCreateShader(type);
    00568
    00569     glShaderSource(shader, 1, &source, &size);
    00570     glCompileShader(shader);
    00571     glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
    00572     if (!result)
    00573     {
    00574         glGetShaderInfoLog(shader, sizeof(log), NULL, log);
    00575         COMP_DEBUG_MSG("Got Fatal Log as " << log);
    00576     }
    00577     glAttachShader(program, shader);
    00578
    00579     if (glGetError() != GL_NO_ERROR)
    00580     {
    00581         COMP_ERROR_MSG("Got gl error as " << glGetError());
    00582     }
    00583 }
    00584
    00585 int
    00586 NvEglRenderer::InitializeShaders(void)
    00587 {
    00588     GLuint program;
    00589     int result = GL_FALSE;
    00590     char log[4096];
    00591     uint32_t pos_location = 0;
    00592     uint32_t tc_location = 0;
    00593
    00594     static const float kVertices[] = {
    00595         -1.f, -1.f,
    00596         1.f, -1.f,
    00597         -1.f, 1.f,
    00598         1.f, 1.f,
    00599     };
    00600     static const float kTextureCoords[] = {
    00601         0.0f, 1.0f,
    00602         1.0f, 1.0f,
    00603         0.0f, 0.0f,
    00604         1.0f, 0.0f,
    00605     };
    00606
    00607     static const char kVertexShader[] = "varying vec2 interp_tc;\n"
    00608         "attribute vec4 in_pos;\n"
    00609         "attribute vec2 in_tc; \n"
    00610         "void main() { \n"
    00611         "interp_tc = in_tc; \n" "gl_Position = in_pos; \n" "}\n";
    00612
    00613     static const char kFragmentShader[] =
    00614         "#extension GL_OES_EGL_image_external : require\n"
    00615         "precision mediump float;\n" "varying vec2 interp_tc; \n"
    00616         "uniform samplerExternalOES tex; \n" "void main() {\n"
    00617         "gl_FragColor = texture2D(tex, interp_tc);\n" "}\n";
    00618
    00619     glEnable(GL_SCISSOR_TEST);
    00620     program = glCreateProgram();
    00621
    00622     CreateShader(program, GL_VERTEX_SHADER, kVertexShader,
    00623                  sizeof(kVertexShader));
    00624     CreateShader(program, GL_FRAGMENT_SHADER, kFragmentShader,
    00625                  sizeof(kFragmentShader));
    00626
    00627     glLinkProgram(program);
    00628     if (glGetError() != GL_NO_ERROR)
    00629     {
    00630         COMP_ERROR_MSG("Got gl error as " << glGetError());
    00631         return -1;
    00632     }
    00633
    00634     glGetProgramiv(program, GL_LINK_STATUS, &result);
    00635     if (!result)
    00636     {
    00637         glGetShaderInfoLog(program, sizeof(log), NULL, log);
    00638         COMP_ERROR_MSG("Error while Linking " << log);
    00639         return -1;
    00640     }
    00641
    00642     glUseProgram(program);
    00643     if (glGetError() != GL_NO_ERROR)
    00644     {
    00645         COMP_ERROR_MSG("Got gl error as " << glGetError());
    00646         return -1;
    00647     }
    00648
    00649     pos_location = glGetAttribLocation(program, "in_pos");
    00650
    00651     glEnableVertexAttribArray(pos_location);
    00652     glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
    00653
    00654     tc_location = glGetAttribLocation(program, "in_tc");
    00655
    00656     glEnableVertexAttribArray(tc_location);
    00657     glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0,
    00658                           kTextureCoords);
    00659
    00660     glActiveTexture(GL_TEXTURE0);
    00661     glUniform1i(glGetUniformLocation(program, "texSampler"), 0);
    00662     if (glGetError() != GL_NO_ERROR)
    00663     {
    00664         COMP_ERROR_MSG("Got gl error as " << glGetError());
    00665         return -1;
    00666     }
    00667     COMP_DEBUG_MSG("Shaders intialized");
    00668     return 0;
    00669 }
    00670
    00671 int
    00672 NvEglRenderer::create_texture()
    00673 {
    00674     int viewport[4];
    00675
    00676     glGetIntegerv(GL_VIEWPORT, viewport);
    00677     glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
    00678     glScissor(viewport[0], viewport[1], viewport[2], viewport[3]);
    00679
    00680     glGenTextures(1, &texture_id);
    00681
    00682     glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
    00683     return 0;
    00684 }