<commit_before>// Modified from chromium/src/webkit/glue/gl_bindings_skia_cmd_buffer.cc

// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gl/GrGLInterface.h"
#include "gl/GrGLAssembleInterface.h"
#include "gl/GrGLExtensions.h"
#include "gl/GrGLUtil.h"

#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <EGL/egl.h>

static GrGLInterface* create_es_interface(GrGLVersion version,
                                          GrGLExtensions* extensions) {
    if (version < GR_GL_VER(2,0)) {
        return NULL;
    }

    GrGLInterface* interface = SkNEW(GrGLInterface);
    interface->fStandard = kGLES_GrGLStandard;
    GrGLInterface::Functions* functions = &interface->fFunctions;

    functions->fActiveTexture = glActiveTexture;
    functions->fAttachShader = glAttachShader;
    functions->fBindAttribLocation = glBindAttribLocation;
    functions->fBindBuffer = glBindBuffer;
    functions->fBindTexture = glBindTexture;
    functions->fBindVertexArray = glBindVertexArrayOES;
    functions->fBlendColor = glBlendColor;
    functions->fBlendFunc = glBlendFunc;
    functions->fBufferData = glBufferData;
    functions->fBufferSubData = glBufferSubData;
    functions->fClear = glClear;
    functions->fClearColor = glClearColor;
    functions->fClearStencil = glClearStencil;
    functions->fColorMask = glColorMask;
    functions->fCompileShader = glCompileShader;
    functions->fCompressedTexImage2D = glCompressedTexImage2D;
    functions->fCopyTexSubImage2D = glCopyTexSubImage2D;
    functions->fCreateProgram = glCreateProgram;
    functions->fCreateShader = glCreateShader;
    functions->fCullFace = glCullFace;
    functions->fDeleteBuffers = glDeleteBuffers;
    functions->fDeleteProgram = glDeleteProgram;
    functions->fDeleteShader = glDeleteShader;
    functions->fDeleteTextures = glDeleteTextures;
    functions->fDeleteVertexArrays = glDeleteVertexArraysOES;
    functions->fDepthMask = glDepthMask;
    functions->fDisable = glDisable;
    functions->fDisableVertexAttribArray = glDisableVertexAttribArray;
    functions->fDrawArrays = glDrawArrays;
    functions->fDrawElements = glDrawElements;
    functions->fEnable = glEnable;
    functions->fEnableVertexAttribArray = glEnableVertexAttribArray;
    functions->fFinish = glFinish;
    functions->fFlush = glFlush;
    functions->fFrontFace = glFrontFace;
    functions->fGenBuffers = glGenBuffers;
    functions->fGenerateMipmap = glGenerateMipmap;
    functions->fGenTextures = glGenTextures;
    functions->fGenVertexArrays = glGenVertexArraysOES;
    functions->fGetBufferParameteriv = glGetBufferParameteriv;
    functions->fGetError = glGetError;
    functions->fGetIntegerv = glGetIntegerv;
    functions->fGetProgramInfoLog = glGetProgramInfoLog;
    functions->fGetProgramiv = glGetProgramiv;
    functions->fGetShaderInfoLog = glGetShaderInfoLog;
    functions->fGetShaderiv = glGetShaderiv;
    functions->fGetString = glGetString;
#if GL_ES_VERSION_3_0
    functions->fGetStringi = glGetStringi;
#else
    functions->fGetStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
#endif
    functions->fGetUniformLocation = glGetUniformLocation;
    functions->fLineWidth = glLineWidth;
    functions->fLinkProgram = glLinkProgram;
    functions->fPixelStorei = glPixelStorei;
    functions->fReadPixels = glReadPixels;
    functions->fScissor = glScissor;
#if GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE
    functions->fShaderSource = (GrGLShaderSourceProc) glShaderSource;
#else
    functions->fShaderSource = glShaderSource;
#endif
    functions->fStencilFunc = glStencilFunc;
    functions->fStencilFuncSeparate = glStencilFuncSeparate;
    functions->fStencilMask = glStencilMask;
    functions->fStencilMaskSeparate = glStencilMaskSeparate;
    functions->fStencilOp = glStencilOp;
    functions->fStencilOpSeparate = glStencilOpSeparate;
    functions->fTexImage2D = glTexImage2D;
    functions->fTexParameteri = glTexParameteri;
    functions->fTexParameteriv = glTexParameteriv;
    functions->fTexSubImage2D = glTexSubImage2D;

    if (version >= GR_GL_VER(3,0)) {
#if GL_ES_VERSION_3_0
        functions->fTexStorage2D = glTexStorage2D;
#else
        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2D");
#endif
    } else {
#if GL_EXT_texture_storage
        functions->fTexStorage2D = glTexStorage2DEXT;
#else
        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2DEXT");
#endif
    }

#if GL_EXT_discard_framebuffer
    functions->fDiscardFramebuffer = glDiscardFramebufferEXT;
#endif
    functions->fUniform1f = glUniform1f;
    functions->fUniform1i = glUniform1i;
    functions->fUniform1fv = glUniform1fv;
    functions->fUniform1iv = glUniform1iv;
    functions->fUniform2f = glUniform2f;
    functions->fUniform2i = glUniform2i;
    functions->fUniform2fv = glUniform2fv;
    functions->fUniform2iv = glUniform2iv;
    functions->fUniform3f = glUniform3f;
    functions->fUniform3i = glUniform3i;
    functions->fUniform3fv = glUniform3fv;
    functions->fUniform3iv = glUniform3iv;
    functions->fUniform4f = glUniform4f;
    functions->fUniform4i = glUniform4i;
    functions->fUniform4fv = glUniform4fv;
    functions->fUniform4iv = glUniform4iv;
    functions->fUniformMatrix2fv = glUniformMatrix2fv;
    functions->fUniformMatrix3fv = glUniformMatrix3fv;
    functions->fUniformMatrix4fv = glUniformMatrix4fv;
    functions->fUseProgram = glUseProgram;
    functions->fVertexAttrib4fv = glVertexAttrib4fv;
    functions->fVertexAttribPointer = glVertexAttribPointer;
    functions->fViewport = glViewport;
    functions->fBindFramebuffer = glBindFramebuffer;
    functions->fBindRenderbuffer = glBindRenderbuffer;
    functions->fCheckFramebufferStatus = glCheckFramebufferStatus;
    functions->fDeleteFramebuffers = glDeleteFramebuffers;
    functions->fDeleteRenderbuffers = glDeleteRenderbuffers;
    functions->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
    functions->fFramebufferTexture2D = glFramebufferTexture2D;

    if (version >= GR_GL_VER(3,0)) {
#if GL_ES_VERSION_3_0
        functions->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample;
        functions->fBlitFramebuffer = glBlitFramebuffer;
#else
        functions->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisample");
        functions->fBlitFramebuffer = (GrGLBlitFramebufferProc) eglGetProcAddress("glBlitFramebuffer");
#endif
    }

    if (extensions->has("GL_EXT_multisampled_render_to_texture")) {
#if GL_EXT_multisampled_render_to_texture
        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleEXT;
        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleEXT;
#else
        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleEXT");
        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleEXT");
#endif
    } else if (extensions->has("GL_IMG_multisampled_render_to_texture")) {
#if GL_IMG_multisampled_render_to_texture
        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleIMG;
#else
        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleIMG");
        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleIMG");
#endif
    }

    functions->fGenFramebuffers = glGenFramebuffers;
    functions->fGenRenderbuffers = glGenRenderbuffers;
    functions->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
    functions->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
    functions->fRenderbufferStorage = glRenderbufferStorage;

#if GL_OES_mapbuffer
    functions->fMapBuffer = glMapBufferOES;
    functions->fUnmapBuffer = glUnmapBufferOES;
#else
    functions->fMapBuffer = (GrGLMapBufferProc) eglGetProcAddress("glMapBufferOES");
    functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES");

#endif

#if GL_ES_VERSION_3_0 || GL_EXT_map_buffer_range
    functions->fMapBufferRange = glMapBufferRange;
    functions->fFlushMappedBufferRange = glFlushMappedBufferRange;
#else
    if (version >= GR_GL_VER(3,0) || extensions->has("GL_EXT_map_buffer_range")) {
        functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRange");
        functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRange");
    }
#endif

    if (extensions->has("GL_EXT_debug_marker")) {
        functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarker");
        functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarker");
        functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGroupMarker");
        // The below check is here because a device has been found that has the extension string but
        // returns NULL from the eglGetProcAddress for the functions
        if (NULL == functions->fInsertEventMarker ||
            NULL == functions->fPushGroupMarker ||
            NULL == functions->fPopGroupMarker) {
            extensions->remove("GL_EXT_debug_marker");
        }
    }

#if GL_ES_VERSION_3_0
    functions->fInvalidateFramebuffer = glInvalidateFramebuffer;
    functions->fInvalidateSubFramebuffer = glInvalidateSubFramebuffer;
#else
    functions->fInvalidateFramebuffer = (GrGLInvalidateFramebufferProc) eglGetProcAddress("glInvalidateFramebuffer");
    functions->fInvalidateSubFramebuffer = (GrGLInvalidateSubFramebufferProc) eglGetProcAddress("glInvalidateSubFramebuffer");
#endif
    functions->fInvalidateBufferData = (GrGLInvalidateBufferDataProc) eglGetProcAddress("glInvalidateBufferData");
    functions->fInvalidateBufferSubData = (GrGLInvalidateBufferSubDataProc) eglGetProcAddress("glInvalidateBufferSubData");
    functions->fInvalidateTexImage = (GrGLInvalidateTexImageProc) eglGetProcAddress("glInvalidateTexImage");
    functions->fInvalidateTexSubImage = (GrGLInvalidateTexSubImageProc) eglGetProcAddress("glInvalidateTexSubImage");

    return interface;
}

static GrGLFuncPtr android_get_gl_proc(void* ctx, const char name[]) {
    SkASSERT(NULL == ctx);
    return eglGetProcAddress(name);
}

static const GrGLInterface* create_desktop_interface() {
    return GrGLAssembleGLInterface(NULL, android_get_gl_proc);
}

const GrGLInterface* GrGLCreateNativeInterface() {

    const char* verStr = reinterpret_cast<const char*>(glGetString(GR_GL_VERSION));
    GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);

    if (kGLES_GrGLStandard == standard) {
        GrGLVersion version = GrGLGetVersionFromString(verStr);
        GrGLExtensions extensions;
        GrGLGetStringiProc getStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
        if (!extensions.init(standard, glGetString, getStringi, glGetIntegerv)) {
            return NULL;
        }
        GrGLInterface* interface = create_es_interface(version, &extensions);

        if (NULL != interface) {
            interface->fExtensions.swap(&extensions);
        }

        return interface;
    } else if (kGL_GrGLStandard == standard) {
        return create_desktop_interface();
    }

    return NULL;
}
<commit_msg>Add EXT suffix to EXT_map_buffer_range references<commit_after>// Modified from chromium/src/webkit/glue/gl_bindings_skia_cmd_buffer.cc

// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gl/GrGLInterface.h"
#include "gl/GrGLAssembleInterface.h"
#include "gl/GrGLExtensions.h"
#include "gl/GrGLUtil.h"

#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <EGL/egl.h>

static GrGLInterface* create_es_interface(GrGLVersion version,
                                          GrGLExtensions* extensions) {
    if (version < GR_GL_VER(2,0)) {
        return NULL;
    }

    GrGLInterface* interface = SkNEW(GrGLInterface);
    interface->fStandard = kGLES_GrGLStandard;
    GrGLInterface::Functions* functions = &interface->fFunctions;

    functions->fActiveTexture = glActiveTexture;
    functions->fAttachShader = glAttachShader;
    functions->fBindAttribLocation = glBindAttribLocation;
    functions->fBindBuffer = glBindBuffer;
    functions->fBindTexture = glBindTexture;
    functions->fBindVertexArray = glBindVertexArrayOES;
    functions->fBlendColor = glBlendColor;
    functions->fBlendFunc = glBlendFunc;
    functions->fBufferData = glBufferData;
    functions->fBufferSubData = glBufferSubData;
    functions->fClear = glClear;
    functions->fClearColor = glClearColor;
    functions->fClearStencil = glClearStencil;
    functions->fColorMask = glColorMask;
    functions->fCompileShader = glCompileShader;
    functions->fCompressedTexImage2D = glCompressedTexImage2D;
    functions->fCopyTexSubImage2D = glCopyTexSubImage2D;
    functions->fCreateProgram = glCreateProgram;
    functions->fCreateShader = glCreateShader;
    functions->fCullFace = glCullFace;
    functions->fDeleteBuffers = glDeleteBuffers;
    functions->fDeleteProgram = glDeleteProgram;
    functions->fDeleteShader = glDeleteShader;
    functions->fDeleteTextures = glDeleteTextures;
    functions->fDeleteVertexArrays = glDeleteVertexArraysOES;
    functions->fDepthMask = glDepthMask;
    functions->fDisable = glDisable;
    functions->fDisableVertexAttribArray = glDisableVertexAttribArray;
    functions->fDrawArrays = glDrawArrays;
    functions->fDrawElements = glDrawElements;
    functions->fEnable = glEnable;
    functions->fEnableVertexAttribArray = glEnableVertexAttribArray;
    functions->fFinish = glFinish;
    functions->fFlush = glFlush;
    functions->fFrontFace = glFrontFace;
    functions->fGenBuffers = glGenBuffers;
    functions->fGenerateMipmap = glGenerateMipmap;
    functions->fGenTextures = glGenTextures;
    functions->fGenVertexArrays = glGenVertexArraysOES;
    functions->fGetBufferParameteriv = glGetBufferParameteriv;
    functions->fGetError = glGetError;
    functions->fGetIntegerv = glGetIntegerv;
    functions->fGetProgramInfoLog = glGetProgramInfoLog;
    functions->fGetProgramiv = glGetProgramiv;
    functions->fGetShaderInfoLog = glGetShaderInfoLog;
    functions->fGetShaderiv = glGetShaderiv;
    functions->fGetString = glGetString;
#if GL_ES_VERSION_3_0
    functions->fGetStringi = glGetStringi;
#else
    functions->fGetStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
#endif
    functions->fGetUniformLocation = glGetUniformLocation;
    functions->fLineWidth = glLineWidth;
    functions->fLinkProgram = glLinkProgram;
    functions->fPixelStorei = glPixelStorei;
    functions->fReadPixels = glReadPixels;
    functions->fScissor = glScissor;
#if GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE
    functions->fShaderSource = (GrGLShaderSourceProc) glShaderSource;
#else
    functions->fShaderSource = glShaderSource;
#endif
    functions->fStencilFunc = glStencilFunc;
    functions->fStencilFuncSeparate = glStencilFuncSeparate;
    functions->fStencilMask = glStencilMask;
    functions->fStencilMaskSeparate = glStencilMaskSeparate;
    functions->fStencilOp = glStencilOp;
    functions->fStencilOpSeparate = glStencilOpSeparate;
    functions->fTexImage2D = glTexImage2D;
    functions->fTexParameteri = glTexParameteri;
    functions->fTexParameteriv = glTexParameteriv;
    functions->fTexSubImage2D = glTexSubImage2D;

    if (version >= GR_GL_VER(3,0)) {
#if GL_ES_VERSION_3_0
        functions->fTexStorage2D = glTexStorage2D;
#else
        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2D");
#endif
    } else {
#if GL_EXT_texture_storage
        functions->fTexStorage2D = glTexStorage2DEXT;
#else
        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2DEXT");
#endif
    }

#if GL_EXT_discard_framebuffer
    functions->fDiscardFramebuffer = glDiscardFramebufferEXT;
#endif
    functions->fUniform1f = glUniform1f;
    functions->fUniform1i = glUniform1i;
    functions->fUniform1fv = glUniform1fv;
    functions->fUniform1iv = glUniform1iv;
    functions->fUniform2f = glUniform2f;
    functions->fUniform2i = glUniform2i;
    functions->fUniform2fv = glUniform2fv;
    functions->fUniform2iv = glUniform2iv;
    functions->fUniform3f = glUniform3f;
    functions->fUniform3i = glUniform3i;
    functions->fUniform3fv = glUniform3fv;
    functions->fUniform3iv = glUniform3iv;
    functions->fUniform4f = glUniform4f;
    functions->fUniform4i = glUniform4i;
    functions->fUniform4fv = glUniform4fv;
    functions->fUniform4iv = glUniform4iv;
    functions->fUniformMatrix2fv = glUniformMatrix2fv;
    functions->fUniformMatrix3fv = glUniformMatrix3fv;
    functions->fUniformMatrix4fv = glUniformMatrix4fv;
    functions->fUseProgram = glUseProgram;
    functions->fVertexAttrib4fv = glVertexAttrib4fv;
    functions->fVertexAttribPointer = glVertexAttribPointer;
    functions->fViewport = glViewport;
    functions->fBindFramebuffer = glBindFramebuffer;
    functions->fBindRenderbuffer = glBindRenderbuffer;
    functions->fCheckFramebufferStatus = glCheckFramebufferStatus;
    functions->fDeleteFramebuffers = glDeleteFramebuffers;
    functions->fDeleteRenderbuffers = glDeleteRenderbuffers;
    functions->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
    functions->fFramebufferTexture2D = glFramebufferTexture2D;

    if (version >= GR_GL_VER(3,0)) {
#if GL_ES_VERSION_3_0
        functions->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample;
        functions->fBlitFramebuffer = glBlitFramebuffer;
#else
        functions->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisample");
        functions->fBlitFramebuffer = (GrGLBlitFramebufferProc) eglGetProcAddress("glBlitFramebuffer");
#endif
    }

    if (extensions->has("GL_EXT_multisampled_render_to_texture")) {
#if GL_EXT_multisampled_render_to_texture
        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleEXT;
        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleEXT;
#else
        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleEXT");
        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleEXT");
#endif
    } else if (extensions->has("GL_IMG_multisampled_render_to_texture")) {
#if GL_IMG_multisampled_render_to_texture
        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleIMG;
#else
        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleIMG");
        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleIMG");
#endif
    }

    functions->fGenFramebuffers = glGenFramebuffers;
    functions->fGenRenderbuffers = glGenRenderbuffers;
    functions->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
    functions->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
    functions->fRenderbufferStorage = glRenderbufferStorage;

#if GL_OES_mapbuffer
    functions->fMapBuffer = glMapBufferOES;
    functions->fUnmapBuffer = glUnmapBufferOES;
#else
    functions->fMapBuffer = (GrGLMapBufferProc) eglGetProcAddress("glMapBufferOES");
    functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES");

#endif

    if (version >= GR_GL_VER(3,0)) {
#if GL_ES_VERSION_3_0
        functions->fMapBufferRange = glMapBufferRange;
        functions->fFlushMappedBufferRange = glFlushMappedBufferRange;
#else
        functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRange");
        functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRange");
#endif
    } else if (extensions->has("GL_EXT_map_buffer_range")) {
#if GL_EXT_map_buffer_range
        functions->fMapBufferRange = glMapBufferRangeEXT;
        functions->fFlushMappedBufferRange = glFlushMappedBufferRangeEXT;
#else
        functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRangeEXT");
        functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRangeEXT");
#endif
    }

    if (extensions->has("GL_EXT_debug_marker")) {
        functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarker");
        functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarker");
        functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGroupMarker");
        // The below check is here because a device has been found that has the extension string but
        // returns NULL from the eglGetProcAddress for the functions
        if (NULL == functions->fInsertEventMarker ||
            NULL == functions->fPushGroupMarker ||
            NULL == functions->fPopGroupMarker) {
            extensions->remove("GL_EXT_debug_marker");
        }
    }

#if GL_ES_VERSION_3_0
    functions->fInvalidateFramebuffer = glInvalidateFramebuffer;
    functions->fInvalidateSubFramebuffer = glInvalidateSubFramebuffer;
#else
    functions->fInvalidateFramebuffer = (GrGLInvalidateFramebufferProc) eglGetProcAddress("glInvalidateFramebuffer");
    functions->fInvalidateSubFramebuffer = (GrGLInvalidateSubFramebufferProc) eglGetProcAddress("glInvalidateSubFramebuffer");
#endif
    functions->fInvalidateBufferData = (GrGLInvalidateBufferDataProc) eglGetProcAddress("glInvalidateBufferData");
    functions->fInvalidateBufferSubData = (GrGLInvalidateBufferSubDataProc) eglGetProcAddress("glInvalidateBufferSubData");
    functions->fInvalidateTexImage = (GrGLInvalidateTexImageProc) eglGetProcAddress("glInvalidateTexImage");
    functions->fInvalidateTexSubImage = (GrGLInvalidateTexSubImageProc) eglGetProcAddress("glInvalidateTexSubImage");

    return interface;
}

static GrGLFuncPtr android_get_gl_proc(void* ctx, const char name[]) {
    SkASSERT(NULL == ctx);
    return eglGetProcAddress(name);
}

static const GrGLInterface* create_desktop_interface() {
    return GrGLAssembleGLInterface(NULL, android_get_gl_proc);
}

const GrGLInterface* GrGLCreateNativeInterface() {

    const char* verStr = reinterpret_cast<const char*>(glGetString(GR_GL_VERSION));
    GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);

    if (kGLES_GrGLStandard == standard) {
        GrGLVersion version = GrGLGetVersionFromString(verStr);
        GrGLExtensions extensions;
        GrGLGetStringiProc getStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
        if (!extensions.init(standard, glGetString, getStringi, glGetIntegerv)) {
            return NULL;
        }
        GrGLInterface* interface = create_es_interface(version, &extensions);

        if (NULL != interface) {
            interface->fExtensions.swap(&extensions);
        }

        return interface;
    } else if (kGL_GrGLStandard == standard) {
        return create_desktop_interface();
    }

    return NULL;
}
<|endoftext|>


<commit_before>#include "iteration/outer/outer_power_iteration.hpp"

#include <memory>

#include "instrumentation/tests/instrument_mock.h"
#include "iteration/group/tests/group_solve_iteration_mock.h"
#include "iteration/subroutine/tests/subroutine_mock.hpp"
#include "eigenvalue/k_effective/tests/k_effective_updater_mock.h"
#include "convergence/tests/final_checker_mock.h"
#include "formulation/updater/tests/fission_source_updater_mock.h"
#include "test_helpers/gmock_wrapper.h"
#include "system/system.hpp"

namespace  {

using namespace bart;

using ::testing::A, ::testing::AtLeast, ::testing::Expectation;
using ::testing::Ref, ::testing::Return, ::testing::Sequence, ::testing::_;

class IterationOuterPowerIterationTest : public ::testing::Test {
 protected:
  using GroupIterator = iteration::group::GroupSolveIterationMock;
  using ConvergenceChecker = convergence::FinalCheckerMock<double>;
  using ConvergenceInstrumentType = instrumentation::InstrumentMock<convergence::Status>;
  using ErrorInstrumentType = instrumentation::InstrumentMock<std::pair<int, double>>;
  using K_EffectiveUpdater = eigenvalue::k_effective::K_EffectiveUpdaterMock;
  using OuterPowerIteration = iteration::outer::OuterPowerIteration;
  using SourceUpdater = formulation::updater::FissionSourceUpdaterMock;
  using StatusInstrumentType = instrumentation::InstrumentMock<std::string>;
  using Subroutine = iteration::subroutine::SubroutineMock;

  std::unique_ptr<OuterPowerIteration> test_iterator;

  // Dependencies
  std::shared_ptr<SourceUpdater> source_updater_ptr_;
  std::shared_ptr<ConvergenceInstrumentType> convergence_instrument_ptr_;
  std::shared_ptr<ErrorInstrumentType> error_instrument_ptr_;
  std::shared_ptr<StatusInstrumentType> status_instrument_ptr_;

  // Supporting objects
  system::System test_system;

  // Observation pointers
  GroupIterator* group_iterator_obs_ptr_;
  ConvergenceChecker* convergence_checker_obs_ptr_;
  K_EffectiveUpdater* k_effective_updater_obs_ptr_;
  Subroutine* post_iteration_subroutine_obs_ptr_;

  // Test parameters
  const int total_groups = 2;
  const int total_angles = 3;
  static constexpr int iterations_ = 4;

  void SetUp() override;
};

void IterationOuterPowerIterationTest::SetUp() {
  // Dependencies
  source_updater_ptr_ = std::make_shared<SourceUpdater>();
  auto group_iterator_ptr = std::make_unique<GroupIterator>();
  group_iterator_obs_ptr_ = group_iterator_ptr.get();
  auto convergenge_checker_ptr = std::make_unique<ConvergenceChecker>();
  convergence_checker_obs_ptr_ = convergenge_checker_ptr.get();
  auto k_effective_updater_ptr = std::make_unique<K_EffectiveUpdater>();
  k_effective_updater_obs_ptr_ = k_effective_updater_ptr.get();
  convergence_instrument_ptr_ = std::make_shared<ConvergenceInstrumentType>();
  status_instrument_ptr_ = std::make_shared<StatusInstrumentType>();
  error_instrument_ptr_ = std::make_shared<ErrorInstrumentType>();
  auto post_iteration_subroutine_ptr = std::make_unique<Subroutine>();
  post_iteration_subroutine_obs_ptr_ = post_iteration_subroutine_ptr.get();

  // Set up system
  test_system.total_angles = total_angles;
  test_system.total_groups = total_groups;

  // Construct test object
  test_iterator = std::make_unique<OuterPowerIteration>(
      std::move(group_iterator_ptr),
      std::move(convergenge_checker_ptr),
      std::move(k_effective_updater_ptr),
      source_updater_ptr_);
  test_iterator->AddPostIterationSubroutine(std::move(post_iteration_subroutine_ptr));

  using ConvergenceStatusPort = iteration::outer::data_names::ConvergenceStatusPort;
  instrumentation::GetPort<ConvergenceStatusPort>(*test_iterator).AddInstrument(
      convergence_instrument_ptr_);
  using StatusPort = iteration::outer::data_names::StatusPort;
  instrumentation::GetPort<StatusPort>(*test_iterator).AddInstrument(
      status_instrument_ptr_);
  using IterationErrorPort = iteration::outer::data_names::IterationErrorPort;
  instrumentation::GetPort<IterationErrorPort>(*test_iterator)
      .AddInstrument(error_instrument_ptr_);
}

TEST_F(IterationOuterPowerIterationTest, Constructor) {
  EXPECT_NE(this->test_iterator, nullptr);
  EXPECT_NE(this->test_iterator->group_iterator_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->source_updater_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->convergence_checker_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->k_effective_updater_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->post_iteration_subroutine_ptr(), nullptr);
  EXPECT_EQ(this->source_updater_ptr_.use_count(), 2);
}

TEST_F(IterationOuterPowerIterationTest, ConstructorErrors) {

  for (int i = 0; i < 4; ++i) {
    auto convergence_checker_ptr = (i == 0) ? nullptr :
        std::make_unique<convergence::FinalCheckerMock<double>>();
    auto k_effective_updater_ptr = (i == 1) ? nullptr :
        std::make_unique<eigenvalue::k_effective::K_EffectiveUpdaterMock>();
    auto source_updater_ptr = (i == 2) ? nullptr : this->source_updater_ptr_;
    auto group_iterator_ptr = (i == 3) ? nullptr :
        std::make_unique<iteration::group::GroupSolveIterationMock>();

    EXPECT_ANY_THROW({
                       iteration::outer::OuterPowerIteration test_iterator(
                           std::move(group_iterator_ptr),
                           std::move(convergence_checker_ptr),
                           std::move(k_effective_updater_ptr),
                           source_updater_ptr);
                     });
  }
}

TEST_F(IterationOuterPowerIterationTest, IterateToConvergenceTest) {

  for (int group = 0; group < this->total_groups; ++group) {
    for (int angle = 0; angle < this->total_angles; ++angle) {
      EXPECT_CALL(*this->source_updater_ptr_, UpdateFissionSource(
          Ref(this->test_system),
          bart::system::EnergyGroup(group),
          quadrature::QuadraturePointIndex(angle)))
          .Times(this->iterations_);
    }
  }

  // K_Effective updater return values
  std::array<double, iterations_ + 1> k_effective_by_iteration;
  k_effective_by_iteration.fill(0);
  Sequence k_effective_calls;
  std::vector<double> expected_errors;

  for (int i = 0; i < this->iterations_; ++i) {
    k_effective_by_iteration.at(i + 1) = i * 1.5;

    EXPECT_CALL(*this->k_effective_updater_obs_ptr_,
                CalculateK_Effective(Ref(this->test_system)))
                .InSequence(k_effective_calls)
                .WillOnce(Return(k_effective_by_iteration.at(i + 1)));

    convergence::Status convergence_status;
    convergence_status.is_complete = (i == (this->iterations_ - 1));
    if (i > 0) {
      double expected_error =
          (k_effective_by_iteration.at(i + 1) - k_effective_by_iteration.at(i))
              / (k_effective_by_iteration.at(i + 1));
      expected_errors.push_back(expected_error);
      convergence_status.delta = expected_error;
    } else {
      convergence_status.delta = std::nullopt;
    }

    EXPECT_CALL(*this->convergence_checker_obs_ptr_,
                CheckFinalConvergence(k_effective_by_iteration.at(i + 1),
                                      k_effective_by_iteration.at(i)))
            .WillOnce(Return(convergence_status));
  }

  EXPECT_CALL(*this->group_iterator_obs_ptr_, Iterate(Ref(this->test_system)))
      .Times(this->iterations_);

  EXPECT_CALL(*this->convergence_instrument_ptr_, Read(_))
      .Times(this->iterations_);
  EXPECT_CALL(*this->post_iteration_subroutine_obs_ptr_, Execute(Ref(this->test_system)))
      .Times(this->iterations_);
  EXPECT_CALL(*this->status_instrument_ptr_, Read(_))
      .Times(AtLeast(this->iterations_));
  EXPECT_CALL(*this->error_instrument_ptr_, Read(_))
      .Times(this->iterations_ - 1);

  this->test_iterator->IterateToConvergence(this->test_system);
}

} // namespace<commit_msg>Added documentation and formatting fixes to tests for OuterPowerIteration.<commit_after>#include "iteration/outer/outer_power_iteration.hpp"

#include <memory>

#include "instrumentation/tests/instrument_mock.h"
#include "iteration/group/tests/group_solve_iteration_mock.h"
#include "iteration/subroutine/tests/subroutine_mock.hpp"
#include "eigenvalue/k_effective/tests/k_effective_updater_mock.h"
#include "convergence/tests/final_checker_mock.h"
#include "formulation/updater/tests/fission_source_updater_mock.h"
#include "test_helpers/gmock_wrapper.h"
#include "system/system.hpp"

namespace  {

using namespace bart;

using ::testing::A, ::testing::AtLeast, ::testing::Expectation;
using ::testing::Ref, ::testing::Return, ::testing::Sequence, ::testing::_;

/* This fixture tests the operation of the OuterPowerIteration class. This is a mediator class so the tests will verify
 * proper mediation between the dependencies and exposure of data to instruments.
 *
 * At the completion of SetUp() the test_iterator pointee object is set up with mock dependencies accessible via
 * the provided observation pointers. Mock instrumentation is accessible via shared pointers.
 * */
class IterationOuterPowerIterationTest : public ::testing::Test {
 protected:
  using GroupIterator = iteration::group::GroupSolveIterationMock;
  using ConvergenceChecker = convergence::FinalCheckerMock<double>;
  using ConvergenceInstrumentType = instrumentation::InstrumentMock<convergence::Status>;
  using ErrorInstrumentType = instrumentation::InstrumentMock<std::pair<int, double>>;
  using K_EffectiveUpdater = eigenvalue::k_effective::K_EffectiveUpdaterMock;
  using OuterPowerIteration = iteration::outer::OuterPowerIteration;
  using SourceUpdater = formulation::updater::FissionSourceUpdaterMock;
  using StatusInstrumentType = instrumentation::InstrumentMock<std::string>;
  using Subroutine = iteration::subroutine::SubroutineMock;

  std::unique_ptr<OuterPowerIteration> test_iterator;

  // Dependencies
  std::shared_ptr<SourceUpdater> source_updater_ptr_{ std::make_shared<SourceUpdater>() };

  // Mock instruments
  std::shared_ptr<ConvergenceInstrumentType> convergence_instrument_ptr_{ std::make_shared<ConvergenceInstrumentType>() };
  std::shared_ptr<ErrorInstrumentType> error_instrument_ptr_{ std::make_shared<ErrorInstrumentType>() };
  std::shared_ptr<StatusInstrumentType> status_instrument_ptr_{ std::make_shared<StatusInstrumentType>() };

  // Supporting objects
  system::System test_system;

  // Observation pointers
  GroupIterator* group_iterator_obs_ptr_;
  ConvergenceChecker* convergence_checker_obs_ptr_;
  K_EffectiveUpdater* k_effective_updater_obs_ptr_;
  Subroutine* post_iteration_subroutine_obs_ptr_;

  // Test parameters
  static constexpr int total_groups{ 2 };
  static constexpr int total_angles{ 3 };
  static constexpr int iterations_{ 4 };

  void SetUp() override;
};

void IterationOuterPowerIterationTest::SetUp() {
  // Dependencies
  auto group_iterator_ptr = std::make_unique<GroupIterator>();
  group_iterator_obs_ptr_ = group_iterator_ptr.get();
  auto convergenge_checker_ptr = std::make_unique<ConvergenceChecker>();
  convergence_checker_obs_ptr_ = convergenge_checker_ptr.get();
  auto k_effective_updater_ptr = std::make_unique<K_EffectiveUpdater>();
  k_effective_updater_obs_ptr_ = k_effective_updater_ptr.get();
  auto post_iteration_subroutine_ptr = std::make_unique<Subroutine>();
  post_iteration_subroutine_obs_ptr_ = post_iteration_subroutine_ptr.get();

  // Set up system
  test_system.total_angles = total_angles;
  test_system.total_groups = total_groups;

  // Construct test object
  test_iterator = std::make_unique<OuterPowerIteration>(
      std::move(group_iterator_ptr),
      std::move(convergenge_checker_ptr),
      std::move(k_effective_updater_ptr),
      source_updater_ptr_);
  test_iterator->AddPostIterationSubroutine(std::move(post_iteration_subroutine_ptr));

  using ConvergenceStatusPort = iteration::outer::data_names::ConvergenceStatusPort;
  instrumentation::GetPort<ConvergenceStatusPort>(*test_iterator).AddInstrument(convergence_instrument_ptr_);
  using StatusPort = iteration::outer::data_names::StatusPort;
  instrumentation::GetPort<StatusPort>(*test_iterator).AddInstrument(status_instrument_ptr_);
  using IterationErrorPort = iteration::outer::data_names::IterationErrorPort;
  instrumentation::GetPort<IterationErrorPort>(*test_iterator).AddInstrument(error_instrument_ptr_);
}

/* Constructor (called in SetUp()) should have stored the correct pointers in the test object */
TEST_F(IterationOuterPowerIterationTest, Constructor) {
  EXPECT_NE(this->test_iterator, nullptr);
  EXPECT_NE(this->test_iterator->group_iterator_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->source_updater_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->convergence_checker_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->k_effective_updater_ptr(), nullptr);
  EXPECT_NE(this->test_iterator->post_iteration_subroutine_ptr(), nullptr);
  EXPECT_EQ(this->source_updater_ptr_.use_count(), 2);
}

/* Constructor should throw an error if pointers passed to dependencies are null. */
TEST_F(IterationOuterPowerIterationTest, ConstructorErrors) {

  for (int i = 0; i < 4; ++i) {
    auto convergence_checker_ptr = (i == 0) ? nullptr :
        std::make_unique<convergence::FinalCheckerMock<double>>();
    auto k_effective_updater_ptr = (i == 1) ? nullptr :
        std::make_unique<eigenvalue::k_effective::K_EffectiveUpdaterMock>();
    auto source_updater_ptr = (i == 2) ? nullptr : this->source_updater_ptr_;
    auto group_iterator_ptr = (i == 3) ? nullptr :
        std::make_unique<iteration::group::GroupSolveIterationMock>();

    EXPECT_ANY_THROW({
                       iteration::outer::OuterPowerIteration test_iterator(
                           std::move(group_iterator_ptr),
                           std::move(convergence_checker_ptr),
                           std::move(k_effective_updater_ptr),
                           source_updater_ptr);
                     });
  }
}

/* A call to Iterate() should properly mediate the calls to the owned classes, including the group iteration class, and
 * convergence-checker. */
TEST_F(IterationOuterPowerIterationTest, IterateToConvergenceTest) {

  for (int group = 0; group < this->total_groups; ++group) {
    for (int angle = 0; angle < this->total_angles; ++angle) {
      EXPECT_CALL(*this->source_updater_ptr_, UpdateFissionSource(Ref(this->test_system),
                                                                  bart::system::EnergyGroup(group),
                                                                  quadrature::QuadraturePointIndex(angle)))
          .Times(this->iterations_);
    }
  }

  // K_Effective updater return values
  std::array<double, iterations_ + 1> k_effective_by_iteration;
  k_effective_by_iteration.fill(0);
  Sequence k_effective_calls;
  std::vector<double> expected_errors;

  for (int i = 0; i < this->iterations_; ++i) {
    const double iteration_k_effective{i * 1.5 };
    k_effective_by_iteration.at(i + 1) = iteration_k_effective;

    EXPECT_CALL(*this->k_effective_updater_obs_ptr_, CalculateK_Effective(Ref(this->test_system)))
        .InSequence(k_effective_calls)
        .WillOnce(Return(iteration_k_effective));

    convergence::Status convergence_status;
    convergence_status.is_complete = (i == (this->iterations_ - 1));
    if (i > 0) {
      double expected_error = (iteration_k_effective - k_effective_by_iteration.at(i)) / (iteration_k_effective);
      expected_errors.push_back(expected_error);
      convergence_status.delta = expected_error;
    } else {
      convergence_status.delta = std::nullopt;
    }

    EXPECT_CALL(*this->convergence_checker_obs_ptr_,
                CheckFinalConvergence(k_effective_by_iteration.at(i + 1), k_effective_by_iteration.at(i)))
        .WillOnce(Return(convergence_status));
  }

  EXPECT_CALL(*this->group_iterator_obs_ptr_, Iterate(Ref(this->test_system)))
      .Times(this->iterations_);

  EXPECT_CALL(*this->convergence_instrument_ptr_, Read(_))
      .Times(this->iterations_);
  EXPECT_CALL(*this->post_iteration_subroutine_obs_ptr_, Execute(Ref(this->test_system)))
      .Times(this->iterations_);
  EXPECT_CALL(*this->status_instrument_ptr_, Read(_))
      .Times(AtLeast(this->iterations_));
  EXPECT_CALL(*this->error_instrument_ptr_, Read(_))
      .Times(this->iterations_ - 1);

  this->test_iterator->IterateToConvergence(this->test_system);
}

} // namespace<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "MediaFile.h"
#include <iostream>
#include <string>
#include <algorithm>

#ifdef WIN32

void ConvertPath(std::string &path)
{
  std::replace(dir.begin(), dir.end(), '/', '\\');
}

#endif

//
// MediaFile
//

MediaFile::MediaFile(std::istream* _stream) : stream(_stream)
{
  // do nothing
}

MediaFile::~MediaFile()
{
  // do nothing
}

bool		MediaFile::isOkay() const
{
  return (stream != NULL && stream->good());
}

void		MediaFile::readRaw(void* vbuffer, uint32_t bytes)
{
  char* buffer = reinterpret_cast<char*>(vbuffer);
  stream->read(buffer, bytes);
}

void		MediaFile::skip(uint32_t bytes)
{
  stream->ignore(bytes);
}

uint16_t	MediaFile::read16LE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16LE(&b);
}

uint16_t	MediaFile::read16BE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16BE(&b);
}

uint32_t	MediaFile::read32LE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32LE(&b);
}

uint32_t	MediaFile::read32BE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32BE(&b);
}

uint16_t	MediaFile::swap16LE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[0]) + (static_cast<uint16_t>(b[1]) << 8);
  return *d;
}

uint16_t	MediaFile::swap16BE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[1]) + (static_cast<uint16_t>(b[0]) << 8);
  return *d;
}

uint32_t	MediaFile::swap32LE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[0]) + (static_cast<uint32_t>(b[1]) << 8) +
       (static_cast<uint32_t>(b[2]) << 16) +
       (static_cast<uint32_t>(b[3]) << 24);
  return *d;
}

uint32_t	MediaFile::swap32BE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[3]) + (static_cast<uint32_t>(b[2]) << 8) +
       (static_cast<uint32_t>(b[1]) << 16) +
       (static_cast<uint32_t>(b[0]) << 24);
  return *d;
}

//
// utility methods to read various media files in any supported format
//

#include "FileManager.h"
#include "SGIImageFile.h"
#include "PNGImageFile.h"
#include "WaveAudioFile.h"

#define OPENMEDIA(_T)					\
do {							\
  stream = FILEMGR.createDataInStream(filename, true);	\
  if (stream == NULL)					\
    stream = FILEMGR.createDataInStream(filename +	\
	     _T::getExtension(), true);			\
  if (stream != NULL) {					\
    file = new _T(stream);				\
    if (!file->isOpen()) {				\
      file = NULL;					\
      delete stream;					\
      stream = NULL;					\
    }							\
  }							\
} while (0)

unsigned char*		MediaFile::readImage(
				const std::string& filename,
				int* width, int* height)
{
#ifdef WIN32
  // cheat and make sure the file is a windows file path
  ConvertPath(filename);
#endif //WIN32
  // try opening file as an image
  std::istream* stream;
  ImageFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(PNGImageFile);
  if (file == NULL)
    OPENMEDIA(SGIImageFile);

  // read the image
  unsigned char* image = NULL;
  if (file != NULL) {
    // get the image size
    int dx = *width  = file->getWidth();
    int dy = *height = file->getHeight();
    int dz =	   file->getNumChannels();

    // make buffer for final image
    image = new unsigned char[dx * dy * 4];

    // make buffer to read image.  if the image file has 4 channels
    // then read directly into the final image buffer.
    unsigned char* buffer = (dz == 4) ? image : new unsigned char[dx * dy * dz];

    // read the image
    if (image != NULL && buffer != NULL) {
      if (!file->read(buffer)) {
	// failed to read image.  clean up.
	if (buffer != image)
	  delete[] buffer;
	delete[] image;
	image  = NULL;
	buffer = NULL;
      } else {
	// expand image into 4 channels
	int n = dx * dy;
	const unsigned char* src = buffer;
	unsigned char* dst = image;
	if (dz == 1) {
	  // r=g=b=i, a=max
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = 0xff;
	    src += 1;
	    dst += 4;
	  }
	} else if (dz == 2) {
	  // r=g=b=i
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = src[1];
	    src += 2;
	    dst += 4;
	  }
	} else if (dz == 3) {
	  // a=max
	  for (; n > 0; --n) {
	    dst[0] = src[0];
	    dst[1] = src[1];
	    dst[2] = src[2];
	    dst[3] = 0xff;
	    src += 3;
	    dst += 4;
	  }
	}
      }
    }

    // clean up
    if (buffer != image)
      delete[] buffer;
    delete file;
  }

  // clean up
  delete stream;

  return image;
}

/*
float*		MediaFile::readSound(
			const std::string& filename,
			int* _numFrames, int* rate)
{
  // try opening as an audio file
  std::istream* stream;
  AudioFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(WaveAudioFile);

  // read the audio
  float* audio = NULL;
  if (file != NULL) {
    // get the audio info
    *rate	   = file->getFramesPerSecond();
    int numChannels = file->getNumChannels();
    int numFrames   = file->getNumFrames();
    int sampleWidth = file->getSampleWidth();

    // make a buffer to read into
    unsigned char* raw = new unsigned char[numFrames * numChannels * sampleWidth];

    // read raw samples
    if (file->read(raw, numFrames)) {
      // prepare conversion parameters
      int step   = 1;
#if defined(HALF_RATE_AUDIO)
      step      *= 2;
      numFrames /= 2;
      *rate     /= 2;
#endif

      // make final audio buffer
      audio = new float[2 * numFrames];

      // convert
      if (numChannels == 1) {
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = 257.0f * static_cast<float>(*src);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = static_cast<float>(*src);
	    src += step;
	  }
	}
      } else {
	step *= 2;
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = 257.0f * static_cast<float>(src[0]);
	    audio[2 * i + 1] = 257.0f * static_cast<float>(src[1]);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = static_cast<float>(src[0]);
	    audio[2 * i + 1] = static_cast<float>(src[1]);
	    src += step;
	  }
	}
      }
    }

    // clean up
    delete[] raw;
    delete file;
    *_numFrames = numFrames;
  }

  // clean up
  delete stream;

  return audio;
}
*/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>fixes for the little people<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "MediaFile.h"
#include <iostream>
#include <string>
#include <algorithm>

#ifdef WIN32

void ConvertPath(const std::string &path)
{
	std::replace(const_cast<std::string &>(path).begin(), const_cast<std::string &>(path).end(), '/', '\\');
}

#endif

//
// MediaFile
//

MediaFile::MediaFile(std::istream* _stream) : stream(_stream)
{
  // do nothing
}

MediaFile::~MediaFile()
{
  // do nothing
}

bool		MediaFile::isOkay() const
{
  return (stream != NULL && stream->good());
}

void		MediaFile::readRaw(void* vbuffer, uint32_t bytes)
{
  char* buffer = reinterpret_cast<char*>(vbuffer);
  stream->read(buffer, bytes);
}

void		MediaFile::skip(uint32_t bytes)
{
  stream->ignore(bytes);
}

uint16_t	MediaFile::read16LE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16LE(&b);
}

uint16_t	MediaFile::read16BE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16BE(&b);
}

uint32_t	MediaFile::read32LE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32LE(&b);
}

uint32_t	MediaFile::read32BE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32BE(&b);
}

uint16_t	MediaFile::swap16LE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[0]) + (static_cast<uint16_t>(b[1]) << 8);
  return *d;
}

uint16_t	MediaFile::swap16BE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[1]) + (static_cast<uint16_t>(b[0]) << 8);
  return *d;
}

uint32_t	MediaFile::swap32LE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[0]) + (static_cast<uint32_t>(b[1]) << 8) +
       (static_cast<uint32_t>(b[2]) << 16) +
       (static_cast<uint32_t>(b[3]) << 24);
  return *d;
}

uint32_t	MediaFile::swap32BE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[3]) + (static_cast<uint32_t>(b[2]) << 8) +
       (static_cast<uint32_t>(b[1]) << 16) +
       (static_cast<uint32_t>(b[0]) << 24);
  return *d;
}

//
// utility methods to read various media files in any supported format
//

#include "FileManager.h"
#include "SGIImageFile.h"
#include "PNGImageFile.h"
#include "WaveAudioFile.h"

#define OPENMEDIA(_T)					\
do {							\
  stream = FILEMGR.createDataInStream(filename, true);	\
  if (stream == NULL)					\
    stream = FILEMGR.createDataInStream(filename +	\
	     _T::getExtension(), true);			\
  if (stream != NULL) {					\
    file = new _T(stream);				\
    if (!file->isOpen()) {				\
      file = NULL;					\
      delete stream;					\
      stream = NULL;					\
    }							\
  }							\
} while (0)

unsigned char*		MediaFile::readImage(
				const std::string& filename,
				int* width, int* height)
{
#ifdef WIN32
  // cheat and make sure the file is a windows file path
  ConvertPath(filename);
#endif //WIN32
  // try opening file as an image
  std::istream* stream;
  ImageFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(PNGImageFile);
  if (file == NULL)
    OPENMEDIA(SGIImageFile);

  // read the image
  unsigned char* image = NULL;
  if (file != NULL) {
    // get the image size
    int dx = *width  = file->getWidth();
    int dy = *height = file->getHeight();
    int dz =	   file->getNumChannels();

    // make buffer for final image
    image = new unsigned char[dx * dy * 4];

    // make buffer to read image.  if the image file has 4 channels
    // then read directly into the final image buffer.
    unsigned char* buffer = (dz == 4) ? image : new unsigned char[dx * dy * dz];

    // read the image
    if (image != NULL && buffer != NULL) {
      if (!file->read(buffer)) {
	// failed to read image.  clean up.
	if (buffer != image)
	  delete[] buffer;
	delete[] image;
	image  = NULL;
	buffer = NULL;
      } else {
	// expand image into 4 channels
	int n = dx * dy;
	const unsigned char* src = buffer;
	unsigned char* dst = image;
	if (dz == 1) {
	  // r=g=b=i, a=max
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = 0xff;
	    src += 1;
	    dst += 4;
	  }
	} else if (dz == 2) {
	  // r=g=b=i
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = src[1];
	    src += 2;
	    dst += 4;
	  }
	} else if (dz == 3) {
	  // a=max
	  for (; n > 0; --n) {
	    dst[0] = src[0];
	    dst[1] = src[1];
	    dst[2] = src[2];
	    dst[3] = 0xff;
	    src += 3;
	    dst += 4;
	  }
	}
      }
    }

    // clean up
    if (buffer != image)
      delete[] buffer;
    delete file;
  }

  // clean up
  delete stream;

  return image;
}

/*
float*		MediaFile::readSound(
			const std::string& filename,
			int* _numFrames, int* rate)
{
  // try opening as an audio file
  std::istream* stream;
  AudioFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(WaveAudioFile);

  // read the audio
  float* audio = NULL;
  if (file != NULL) {
    // get the audio info
    *rate	   = file->getFramesPerSecond();
    int numChannels = file->getNumChannels();
    int numFrames   = file->getNumFrames();
    int sampleWidth = file->getSampleWidth();

    // make a buffer to read into
    unsigned char* raw = new unsigned char[numFrames * numChannels * sampleWidth];

    // read raw samples
    if (file->read(raw, numFrames)) {
      // prepare conversion parameters
      int step   = 1;
#if defined(HALF_RATE_AUDIO)
      step      *= 2;
      numFrames /= 2;
      *rate     /= 2;
#endif

      // make final audio buffer
      audio = new float[2 * numFrames];

      // convert
      if (numChannels == 1) {
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = 257.0f * static_cast<float>(*src);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = static_cast<float>(*src);
	    src += step;
	  }
	}
      } else {
	step *= 2;
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = 257.0f * static_cast<float>(src[0]);
	    audio[2 * i + 1] = 257.0f * static_cast<float>(src[1]);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = static_cast<float>(src[0]);
	    audio[2 * i + 1] = static_cast<float>(src[1]);
	    src += step;
	  }
	}
      }
    }

    // clean up
    delete[] raw;
    delete file;
    *_numFrames = numFrames;
  }

  // clean up
  delete stream;

  return audio;
}
*/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>#include "itemapi.h"
#include "entitycomponents.h"

using namespace RoseCommon;

ItemAPI::ItemAPI(sol::environment&& env) : LuaAPI(std::move(env)) {
      // build the C++/lua connectors here
      env_.set_function("getAttr", [this](void* entity, std::string attr) {
        throw_assert(entity, "The entity cannot be nullptr");
        Entity e = *(Entity*)entity;
        logger_->info("getAttr called for client {} and attr {}", getId(e), attr);
        return 42;
      });

      env_.set_function("setAttr", [this](void* entity, std::string attr, int32_t value) {
        throw_assert(entity, "The entity cannot be nullptr");
        Entity e = *(Entity*)entity;
        logger_->info("setAttr called for client {} and attr {} value {}", getId(e), attr, value);
      }
    }
<commit_msg>Update lua API<commit_after>#include "itemapi.h"
#include "entitycomponents.h"

using namespace RoseCommon;

ItemAPI::ItemAPI(sol::environment&& env) : LuaAPI(std::move(env)) {
      // build the C++/lua connectors here
      env_.set_function("getAttr", [this](void* entity, std::string attr) {
        throw_assert(entity, "The entity cannot be nullptr");
        Entity e = *(Entity*)entity;
        logger_->info("getAttr called for client {} and attr {}", getId(e), attr);
        return 42;
      });

      env_.set_function("addBonusAttr", [this](void* entity, std::string attr, int32_t value) {
        throw_assert(entity, "The entity cannot be nullptr");
        Entity e = *(Entity*)entity;
        logger_->info("addBonusAttr called for client {} and attr {} value {}", getId(e), attr, value);
      });

      env_.set_function("removeBonusAttr", [this](void* entity, std::string attr, int32_t value) {
        throw_assert(entity, "The entity cannot be nullptr");
        Entity e = *(Entity*)entity;
        logger_->info("removeBonusAttr called for client {} and attr {} value {}", getId(e), attr, value);
      });
    }
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: nadavs@google.com <Nadav Samet>
//         Jin Qing (http://blog.csdn.net/jq0123)

#include "connection_manager.hpp"

#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>
#include <map>
#include <ostream>
#include <sstream>
#include <stddef.h>
#include <string>
#include <utility>
#include <vector>

#include <zmq.hpp>
#include <google/protobuf/stubs/common.h>

#include "application_options.hpp"
#include "client_connection.hpp"
#include "connection.hpp"
#include "broker_thread.hpp"
#include "internal_commands.hpp"
#include "logging.hpp"
#include "rpcz/callback.hpp"
#include "rpcz/sync_event.hpp"
#include "zmq_utils.hpp"

#include "request_handler.hpp"  // TODO: extract worker_thread

namespace rpcz {

connection_manager::weak_ptr connection_manager::this_weak_ptr_;
boost::mutex connection_manager::this_weak_ptr_mutex_;

void worker_thread(connection_manager* connection_manager,
                  zmq::context_t & context, std::string endpoint) {
  zmq::socket_t socket(context, ZMQ_DEALER);
  socket.connect(endpoint.c_str());
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kReady);
  bool should_quit = false;
  while (!should_quit) {
    message_iterator iter(socket);
    CHECK_EQ(0, iter.next().size());
    char command(interpret_message<char>(iter.next()));
    switch (command) {
      case kWorkerQuit:
        should_quit = true;
        break;
      case krunclosure:
        interpret_message<closure*>(iter.next())->run();
        break;
      case kHandleRequest: {
        request_handler * handler =
            interpret_message<request_handler*>(iter.next());
        assert(handler);
        handler->handle_request(iter);
        }
        break;
      case kInvokeclient_request_callback: {
        client_request_callback cb =
            interpret_message<client_request_callback>(
                iter.next());
        connection_manager_status status = connection_manager_status(
            interpret_message<uint64>(iter.next()));
        cb(status, iter);
      }
    }
  }
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kWorkerDone);
}

connection_manager::connection_manager()
  : context_(NULL),
    frontend_endpoint_("inproc://" + boost::lexical_cast<std::string>(this)
        + ".rpcz.connection_manager.frontend"),
    is_terminating_(new sync_event)  // scoped_ptr
{
  DLOG(INFO) << "connection_manager() ";
  application_options options;
  context_ = options.get_zmq_context();
  if (NULL == context_)
  {
      int zmq_io_threads = options.get_zmq_io_threads();
      assert(zmq_io_threads > 0);
      own_context_.reset(new zmq::context_t(zmq_io_threads));
      context_ = own_context_.get();
  }
  assert(context_);
  zmq::socket_t* frontend_socket = new zmq::socket_t(*context_, ZMQ_ROUTER);
  int linger_ms = 0;
  frontend_socket->setsockopt(ZMQ_LINGER, &linger_ms, sizeof(linger_ms));
  frontend_socket->bind(frontend_endpoint_.c_str());
  int nthreads = options.get_connection_manager_threads();
  assert(nthreads > 0);
  for (int i = 0; i < nthreads; ++i) {
    worker_threads_.add_thread(
        new boost::thread(&worker_thread, this, boost::ref(*context_), frontend_endpoint_));
  }
  sync_event event;
  broker_thread_ = boost::thread(&broker_thread::run,
                                 boost::ref(*context_), nthreads, &event,
                                 frontend_socket);
  event.wait();
}

connection_manager_ptr connection_manager::get_new()
{
  lock_guard lock(this_weak_ptr_mutex_);
  connection_manager_ptr p = this_weak_ptr_.lock();
  if (p) return p;
  p.reset(new connection_manager);
  this_weak_ptr_ = p;
  return p;
}

bool connection_manager::is_destroyed()
{
    return 0 == this_weak_ptr_.use_count();
}

// used by get_frontend_socket()
zmq::socket_t& connection_manager::new_frontend_socket() {
    assert(NULL == socket_.get());
    zmq::socket_t* socket = new zmq::socket_t(*context_, ZMQ_DEALER);
    int linger_ms = 0;
    socket->setsockopt(ZMQ_LINGER, &linger_ms, sizeof(linger_ms));
    socket->connect(frontend_endpoint_.c_str());
    assert(NULL == socket_.get());
    socket_.reset(socket);  // set thread specific socket
    return *socket;
}

connection connection_manager::connect(const std::string& endpoint) {
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kConnect, ZMQ_SNDMORE);
  send_string(&socket, endpoint, 0);
  zmq::message_t msg;
  socket.recv(&msg);
  socket.recv(&msg);
  uint64 connection_id = interpret_message<uint64>(msg);
  return connection(connection_id);
}

void connection_manager::bind(const std::string& endpoint,
    const service_factory_map & factories) {
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kBind, ZMQ_SNDMORE);
  send_string(&socket, endpoint, ZMQ_SNDMORE);
  send_pointer(&socket, &factories, 0);
  zmq::message_t msg;
  socket.recv(&msg);
  socket.recv(&msg);
}

// Unbind socket and unregister server_function.
void connection_manager::unbind(const std::string& endpoint)
{
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kUnbind, ZMQ_SNDMORE);
  send_string(&socket, endpoint, 0);
  zmq::message_t msg;
  socket.recv(&msg);
  socket.recv(&msg);
}

void connection_manager::add(closure* closure) {
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, krunclosure, ZMQ_SNDMORE);
  send_pointer(&socket, closure, 0);
  return;
}

void connection_manager::run() {
  is_terminating_->wait();
}

void connection_manager::terminate() {
  is_terminating_->signal();
}

connection_manager::~connection_manager() {
  DLOG(INFO) << "~connection_manager()";
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kQuit, 0);
  broker_thread_.join();
  worker_threads_.join_all();
  DLOG(INFO) << "All threads joined.";
}

}  // namespace rpcz
<commit_msg>fix warn<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: nadavs@google.com <Nadav Samet>
//         Jin Qing (http://blog.csdn.net/jq0123)

#include "connection_manager.hpp"

#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>
#include <map>
#include <ostream>
#include <sstream>
#include <stddef.h>
#include <string>
#include <utility>
#include <vector>

#include <zmq.hpp>
#include <google/protobuf/stubs/common.h>

#include "application_options.hpp"
#include "client_connection.hpp"
#include "connection.hpp"
#include "broker_thread.hpp"
#include "internal_commands.hpp"
#include "logging.hpp"
#include "rpcz/callback.hpp"
#include "rpcz/sync_event.hpp"
#include "zmq_utils.hpp"

#include "request_handler.hpp"  // TODO: extract worker_thread

namespace rpcz {

connection_manager::weak_ptr connection_manager::this_weak_ptr_;
boost::mutex connection_manager::this_weak_ptr_mutex_;

void worker_thread(connection_manager* connection_manager,
                  zmq::context_t & context, std::string endpoint) {
  zmq::socket_t socket(context, ZMQ_DEALER);
  socket.connect(endpoint.c_str());
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kReady);
  bool should_quit = false;
  while (!should_quit) {
    message_iterator iter(socket);
    CHECK_EQ(0, iter.next().size());
    char command(interpret_message<char>(iter.next()));
    switch (command) {
      case kWorkerQuit:
        should_quit = true;
        break;
      case krunclosure:
        interpret_message<closure*>(iter.next())->run();
        break;
      case kHandleRequest: {
        request_handler * handler =
            interpret_message<request_handler*>(iter.next());
        assert(handler);
        handler->handle_request(iter);
        }
        break;
      case kInvokeclient_request_callback: {
        client_request_callback cb =
            interpret_message<client_request_callback>(
                iter.next());
        connection_manager_status status = connection_manager_status(
            interpret_message<uint64>(iter.next()));
        cb(status, iter);
      }
    }
  }
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kWorkerDone);
}

connection_manager::connection_manager()
  : context_(NULL),
    is_terminating_(new sync_event)  // scoped_ptr
{
  DLOG(INFO) << "connection_manager() ";
  frontend_endpoint_ = "inproc://" + boost::lexical_cast<std::string>(this)
      + ".rpcz.connection_manager.frontend";

  application_options options;
  context_ = options.get_zmq_context();
  if (NULL == context_)
  {
      int zmq_io_threads = options.get_zmq_io_threads();
      assert(zmq_io_threads > 0);
      own_context_.reset(new zmq::context_t(zmq_io_threads));
      context_ = own_context_.get();
  }
  assert(context_);
  zmq::socket_t* frontend_socket = new zmq::socket_t(*context_, ZMQ_ROUTER);
  int linger_ms = 0;
  frontend_socket->setsockopt(ZMQ_LINGER, &linger_ms, sizeof(linger_ms));
  frontend_socket->bind(frontend_endpoint_.c_str());
  int nthreads = options.get_connection_manager_threads();
  assert(nthreads > 0);
  for (int i = 0; i < nthreads; ++i) {
    worker_threads_.add_thread(
        new boost::thread(&worker_thread, this, boost::ref(*context_), frontend_endpoint_));
  }
  sync_event event;
  broker_thread_ = boost::thread(&broker_thread::run,
                                 boost::ref(*context_), nthreads, &event,
                                 frontend_socket);
  event.wait();
}

connection_manager_ptr connection_manager::get_new()
{
  lock_guard lock(this_weak_ptr_mutex_);
  connection_manager_ptr p = this_weak_ptr_.lock();
  if (p) return p;
  p.reset(new connection_manager);
  this_weak_ptr_ = p;
  return p;
}

bool connection_manager::is_destroyed()
{
    return 0 == this_weak_ptr_.use_count();
}

// used by get_frontend_socket()
zmq::socket_t& connection_manager::new_frontend_socket() {
    assert(NULL == socket_.get());
    zmq::socket_t* socket = new zmq::socket_t(*context_, ZMQ_DEALER);
    int linger_ms = 0;
    socket->setsockopt(ZMQ_LINGER, &linger_ms, sizeof(linger_ms));
    socket->connect(frontend_endpoint_.c_str());
    assert(NULL == socket_.get());
    socket_.reset(socket);  // set thread specific socket
    return *socket;
}

connection connection_manager::connect(const std::string& endpoint) {
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kConnect, ZMQ_SNDMORE);
  send_string(&socket, endpoint, 0);
  zmq::message_t msg;
  socket.recv(&msg);
  socket.recv(&msg);
  uint64 connection_id = interpret_message<uint64>(msg);
  return connection(connection_id);
}

void connection_manager::bind(const std::string& endpoint,
    const service_factory_map & factories) {
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kBind, ZMQ_SNDMORE);
  send_string(&socket, endpoint, ZMQ_SNDMORE);
  send_pointer(&socket, &factories, 0);
  zmq::message_t msg;
  socket.recv(&msg);
  socket.recv(&msg);
}

// Unbind socket and unregister server_function.
void connection_manager::unbind(const std::string& endpoint)
{
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kUnbind, ZMQ_SNDMORE);
  send_string(&socket, endpoint, 0);
  zmq::message_t msg;
  socket.recv(&msg);
  socket.recv(&msg);
}

void connection_manager::add(closure* closure) {
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, krunclosure, ZMQ_SNDMORE);
  send_pointer(&socket, closure, 0);
  return;
}

void connection_manager::run() {
  is_terminating_->wait();
}

void connection_manager::terminate() {
  is_terminating_->signal();
}

connection_manager::~connection_manager() {
  DLOG(INFO) << "~connection_manager()";
  zmq::socket_t& socket = get_frontend_socket();
  send_empty_message(&socket, ZMQ_SNDMORE);
  send_char(&socket, kQuit, 0);
  broker_thread_.join();
  worker_threads_.join_all();
  DLOG(INFO) << "All threads joined.";
}

}  // namespace rpcz
<|endoftext|>


<commit_before>#include "mitpi.h"

#define GPIO_BASE 0x20200000 //base address of the GPIO control registers.
#define PAGE_SIZE 4096 //mmap maps pages of memory, so we must give it multiples of this size
#define GPFSEL0   0x00000000 //gpio function select. There are 6 of these (32 bit registers)
//bits 2-0 of GPFSEL0: set to 000 to make Pin 0 an output. 001 is an input. Other combinations represent alternate functions
//bits 3-5 are for pin 1.
//...
//bits 27-29 are for pin 9.
//GPFSEL1 repeats, but bits 2-0 are Pin 10, 27-29 are pin 19.
//...
#define GPSET0    0x0000001C //GPIO Pin Output Set. There are 2 of these (32 bit registers)
#define GPSET1    0x00000020
//writing a '1' to bit N of GPSET0 makes that pin HIGH.
//writing a '0' has no effect.
//GPSET0[0-31] maps to pins 0-31
//GPSET1[0-21] maps to pins 32-53
#define GPCLR0    0x00000028 //GPIO Pin Output Clear. There are 2 of these (32 bits each)
#define GPCLR1    0x0000002C
//GPCLR acts the same way as GPSET, but clears the pin instead.
#define GPLEV0    0x00000034 //GPIO Pin Level. There are 2 of these (32 bits each)
#define GPPUD     0x00000094 //GPIO Pull-up/down register. Write 1 for pd, 2 for pu, and then write the PUDCLK
#define GPPUDCLK0 0x00000098 //GPIO Pull-up/down clock. Have to send a clock signal to the pull-up/down resistors to activate them.
#define GPPUDCLK1 0x000000a0 //second register for GPPUDCLK (first is for pins 0-31, 2nd for the rest)

#define TIMER_BASE 0x20003000
#define TIMER_CLO 0x00000004 //lower 32-bits of 1 MHz timer
#define TIMER_CHI 0x00000008 //upper 32-bits

#include <sys/mman.h> //for mmap
#include <sys/time.h>
#include <time.h> //for nanosleep / usleep (if have -std=gnu99)
#include <unistd.h> //for usleep
#include <stdlib.h> //for exit
#include <cassert> //for assert
#include <fcntl.h> //for file opening
#include "common/logging.h"

namespace mitpi {

volatile uint32_t *gpioBaseMem = nullptr;
volatile uint32_t *timerBaseMem = nullptr;

void assertValidPin(int pin) {
    (void)pin; //unused when assertions are disabled.
    assert(pin >= 0 && pin < 64);
}

void writeBitmasked(volatile uint32_t *dest, uint32_t mask, uint32_t value) {
    //set bits designated by (mask) at the address (dest) to (value), without affecting the other bits
    //eg if x = 0b11001100
    //  writeBitmasked(&x, 0b00000110, 0b11110011),
    //  then x now = 0b11001110
    uint32_t cur = *dest;
    uint32_t revised = (cur & (~mask)) | (value & mask);
    *dest = revised;
    *dest = revised; //best to be safe when crossing memory boundaries
}

volatile uint32_t* mapPeripheral(int memfd, int addr) {
    ///dev/mem behaves as a file. We need to map that file into memory:
    //NULL = virtual address of mapping is chosen by kernel.
    //PAGE_SIZE = map 1 page.
    //PROT_READ|PROT_WRITE means give us read and write priveliges to the memory
    //MAP_SHARED means updates to the mapped memory should be written back to the file & shared with other processes
    //addr = offset in file to map
    void *mapped = mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, addr);
    //now, *mapped = memory at physical address of addr.
    if (mapped == MAP_FAILED) {
        LOGE("MitPi::mapPeripheral failed to map memory (did you remember to run as root?)\n");
        exit(1);
    } else {
        LOGV("MitPi::mapPeripheral mapped: %p\n", mapped);
    }
    return (volatile uint32_t*)mapped;
}

bool init() {
    if (gpioBaseMem) {
        return 0; //already initialized
    }
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    if (memfd < 0) {
        LOGE("Failed to open /dev/mem (did you remember to run as root?)\n");
        exit(1);
    }
    gpioBaseMem = mapPeripheral(memfd, GPIO_BASE);
    timerBaseMem = mapPeripheral(memfd, TIMER_BASE);
    return 0; //init OK
}

void makeOutput(int pin) {
    assertValidPin(pin);
    volatile uint32_t *fselAddr = (volatile uint32_t*)(gpioBaseMem + GPFSEL0/4 + pin/10);
    writeBitmasked(fselAddr, 0x7 << (3*(pin%10)), 0x1 << (3*(pin%10))); //0x7  is bitmask to select just our pin, 0x1 is mode to make pin an output
}
void makeInput(int pin) {
    assertValidPin(pin);
    volatile uint32_t *fselAddr = (volatile uint32_t*)(gpioBaseMem + GPFSEL0/4 + pin/10);
    writeBitmasked(fselAddr, 0x7 << (3*(pin%10)), 0x0 << (3*(pin%10))); //0x7 is bitmask to select just our pin, 0x0 is mode to make pin an input
}
void setPinHigh(int pin) {
    assertValidPin(pin);
    //first, select the appropriate register. The first register controls pins 0-31, the second pins 32-63.
    volatile uint32_t *gpSetAddr = (volatile uint32_t*)(gpioBaseMem + GPSET0/4 + (pin/32));
    //now write a 1 ONLY to our pin. The act of writing a 1 to the address triggers it to be set high.
    *gpSetAddr = 1 << (pin & 31);
}
void setPinLow(int pin) {
    assertValidPin(pin);
    //first, select the appropriate register. The first register controls pins 0-31, the second pins 32-63.
    volatile uint32_t *gpClrAddr = (volatile uint32_t*)(gpioBaseMem + GPCLR0/4 + (pin/32));
    //now write a 1 ONLY to our pin. The act of writing a 1 to the address triggers it to be set high.
    *gpClrAddr = 1 << (pin & 31);
}
void setPinState(int pin, bool state) {
    state ? setPinHigh(pin) : setPinLow(pin);
}
bool readPinState(int pin) {
    assertValidPin(pin);
    volatile uint32_t* gpLevAddr = (volatile uint32_t*)(gpioBaseMem + GPLEV0/4 + (pin/32));
    uint32_t value = *gpLevAddr;
    return (value & (1 << (pin & 31))) ? 1 : 0;
}

void setPinPull(int pin, GpioPull pull) {
    assertValidPin(pin);
    volatile uint32_t *pudAddr = (volatile uint32_t*)(gpioBaseMem + GPPUD/4);
    volatile uint32_t *pudClkAddr = (volatile uint32_t*)(gpioBaseMem + GPPUDCLK0/4 + pin/32);
    *pudAddr = pull;
    usleep(10);
    *pudClkAddr = 1 << (pin & 31);
    usleep(10);
    *pudAddr = GPIOPULL_NONE;
    *pudClkAddr = 0;
}

void usleep(unsigned int us) {
    //explicitly exposed to allow users of the library access to a usleep function
    ::usleep(us);
}

uint64_t readSysTime() {
    return ((uint64_t)*(timerBaseMem + TIMER_CHI/4) << 32) + (uint64_t)(*(timerBaseMem + TIMER_CLO/4));
}

}
<commit_msg>Correctly prefix private functions with static<commit_after>#include "mitpi.h"

#define GPIO_BASE 0x20200000 //base address of the GPIO control registers.
#define PAGE_SIZE 4096 //mmap maps pages of memory, so we must give it multiples of this size
#define GPFSEL0   0x00000000 //gpio function select. There are 6 of these (32 bit registers)
//bits 2-0 of GPFSEL0: set to 000 to make Pin 0 an output. 001 is an input. Other combinations represent alternate functions
//bits 3-5 are for pin 1.
//...
//bits 27-29 are for pin 9.
//GPFSEL1 repeats, but bits 2-0 are Pin 10, 27-29 are pin 19.
//...
#define GPSET0    0x0000001C //GPIO Pin Output Set. There are 2 of these (32 bit registers)
#define GPSET1    0x00000020
//writing a '1' to bit N of GPSET0 makes that pin HIGH.
//writing a '0' has no effect.
//GPSET0[0-31] maps to pins 0-31
//GPSET1[0-21] maps to pins 32-53
#define GPCLR0    0x00000028 //GPIO Pin Output Clear. There are 2 of these (32 bits each)
#define GPCLR1    0x0000002C
//GPCLR acts the same way as GPSET, but clears the pin instead.
#define GPLEV0    0x00000034 //GPIO Pin Level. There are 2 of these (32 bits each)
#define GPPUD     0x00000094 //GPIO Pull-up/down register. Write 1 for pd, 2 for pu, and then write the PUDCLK
#define GPPUDCLK0 0x00000098 //GPIO Pull-up/down clock. Have to send a clock signal to the pull-up/down resistors to activate them.
#define GPPUDCLK1 0x000000a0 //second register for GPPUDCLK (first is for pins 0-31, 2nd for the rest)

#define TIMER_BASE 0x20003000
#define TIMER_CLO 0x00000004 //lower 32-bits of 1 MHz timer
#define TIMER_CHI 0x00000008 //upper 32-bits

#include <sys/mman.h> //for mmap
#include <sys/time.h>
#include <time.h> //for nanosleep / usleep (if have -std=gnu99)
#include <unistd.h> //for usleep
#include <stdlib.h> //for exit
#include <cassert> //for assert
#include <fcntl.h> //for file opening
#include "common/logging.h"

namespace mitpi {

static volatile uint32_t *gpioBaseMem = nullptr;
static volatile uint32_t *timerBaseMem = nullptr;

static void assertValidPin(int pin) {
    (void)pin; //unused when assertions are disabled.
    assert(pin >= 0 && pin < 64);
}

static void writeBitmasked(volatile uint32_t *dest, uint32_t mask, uint32_t value) {
    //set bits designated by (mask) at the address (dest) to (value), without affecting the other bits
    //eg if x = 0b11001100
    //  writeBitmasked(&x, 0b00000110, 0b11110011),
    //  then x now = 0b11001110
    uint32_t cur = *dest;
    uint32_t revised = (cur & (~mask)) | (value & mask);
    *dest = revised;
    *dest = revised; //best to be safe when crossing memory boundaries
}

volatile uint32_t* mapPeripheral(int memfd, int addr) {
    ///dev/mem behaves as a file. We need to map that file into memory:
    //NULL = virtual address of mapping is chosen by kernel.
    //PAGE_SIZE = map 1 page.
    //PROT_READ|PROT_WRITE means give us read and write priveliges to the memory
    //MAP_SHARED means updates to the mapped memory should be written back to the file & shared with other processes
    //addr = offset in file to map
    void *mapped = mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, addr);
    //now, *mapped = memory at physical address of addr.
    if (mapped == MAP_FAILED) {
        LOGE("MitPi::mapPeripheral failed to map memory (did you remember to run as root?)\n");
        exit(1);
    } else {
        LOGV("MitPi::mapPeripheral mapped: %p\n", mapped);
    }
    return (volatile uint32_t*)mapped;
}

bool init() {
    if (gpioBaseMem) {
        return 0; //already initialized
    }
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    if (memfd < 0) {
        LOGE("Failed to open /dev/mem (did you remember to run as root?)\n");
        exit(1);
    }
    gpioBaseMem = mapPeripheral(memfd, GPIO_BASE);
    timerBaseMem = mapPeripheral(memfd, TIMER_BASE);
    return 0; //init OK
}

void makeOutput(int pin) {
    assertValidPin(pin);
    volatile uint32_t *fselAddr = (volatile uint32_t*)(gpioBaseMem + GPFSEL0/4 + pin/10);
    writeBitmasked(fselAddr, 0x7 << (3*(pin%10)), 0x1 << (3*(pin%10))); //0x7  is bitmask to select just our pin, 0x1 is mode to make pin an output
}
void makeInput(int pin) {
    assertValidPin(pin);
    volatile uint32_t *fselAddr = (volatile uint32_t*)(gpioBaseMem + GPFSEL0/4 + pin/10);
    writeBitmasked(fselAddr, 0x7 << (3*(pin%10)), 0x0 << (3*(pin%10))); //0x7 is bitmask to select just our pin, 0x0 is mode to make pin an input
}
void setPinHigh(int pin) {
    assertValidPin(pin);
    //first, select the appropriate register. The first register controls pins 0-31, the second pins 32-63.
    volatile uint32_t *gpSetAddr = (volatile uint32_t*)(gpioBaseMem + GPSET0/4 + (pin/32));
    //now write a 1 ONLY to our pin. The act of writing a 1 to the address triggers it to be set high.
    *gpSetAddr = 1 << (pin & 31);
}
void setPinLow(int pin) {
    assertValidPin(pin);
    //first, select the appropriate register. The first register controls pins 0-31, the second pins 32-63.
    volatile uint32_t *gpClrAddr = (volatile uint32_t*)(gpioBaseMem + GPCLR0/4 + (pin/32));
    //now write a 1 ONLY to our pin. The act of writing a 1 to the address triggers it to be set high.
    *gpClrAddr = 1 << (pin & 31);
}
void setPinState(int pin, bool state) {
    state ? setPinHigh(pin) : setPinLow(pin);
}
bool readPinState(int pin) {
    assertValidPin(pin);
    volatile uint32_t* gpLevAddr = (volatile uint32_t*)(gpioBaseMem + GPLEV0/4 + (pin/32));
    uint32_t value = *gpLevAddr;
    return (value & (1 << (pin & 31))) ? 1 : 0;
}

void setPinPull(int pin, GpioPull pull) {
    assertValidPin(pin);
    volatile uint32_t *pudAddr = (volatile uint32_t*)(gpioBaseMem + GPPUD/4);
    volatile uint32_t *pudClkAddr = (volatile uint32_t*)(gpioBaseMem + GPPUDCLK0/4 + pin/32);
    *pudAddr = pull;
    usleep(10);
    *pudClkAddr = 1 << (pin & 31);
    usleep(10);
    *pudAddr = GPIOPULL_NONE;
    *pudClkAddr = 0;
}

void usleep(unsigned int us) {
    //explicitly exposed to allow users of the library access to a usleep function
    ::usleep(us);
}

uint64_t readSysTime() {
    return ((uint64_t)*(timerBaseMem + TIMER_CHI/4) << 32) + (uint64_t)(*(timerBaseMem + TIMER_CLO/4));
}

}
<|endoftext|>