diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-04-01 17:47:19 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-04-01 17:47:19 +0400 |
commit | 5524ed9ba2d60331abed47c9df0bc2fcf330b36b (patch) | |
tree | e8380010f140f022b77236af171d97083a294006 /intern | |
parent | 1360bb6fb0bf0c5c14235c47bf1399accbcecc6f (diff) | |
parent | 689f3aa174ff795044a4dab719edf60b7b1f5bd3 (diff) |
Merged changes in the trunk up to revision 55700.
Conflicts resolved:
source/blender/editors/mesh/mesh_intern.h
Diffstat (limited to 'intern')
23 files changed, 707 insertions, 84 deletions
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp index 47bfe4e69b9..c359c5ec3e2 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp @@ -41,53 +41,65 @@ extern "C" { #include "ffmpeg_compat.h" } -int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer) +int AUD_FFMPEGReader::decode(AVPacket& packet, AUD_Buffer& buffer) { - // save packet parameters - uint8_t *audio_pkg_data = packet->data; - int audio_pkg_size = packet->size; + AVFrame* frame = NULL; + int got_frame; + int read_length; + uint8_t* orig_data = packet.data; + int orig_size = packet.size; int buf_size = buffer.getSize(); int buf_pos = 0; - int read_length, data_size; - - AVPacket tmp_pkt; - - av_init_packet(&tmp_pkt); - - // as long as there is still data in the package - while(audio_pkg_size > 0) + while(packet.size > 0) { - // resize buffer if needed - if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE) - { - buffer.resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true); - buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE; - } - - // read samples from the packet - data_size = buf_size - buf_pos; - - tmp_pkt.data = audio_pkg_data; - tmp_pkt.size = audio_pkg_size; + got_frame = 0; - read_length = avcodec_decode_audio3( - m_codecCtx, - (int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos), - &data_size, &tmp_pkt); + if(!frame) + frame = avcodec_alloc_frame(); + else + avcodec_get_frame_defaults(frame); - // read error, next packet! + read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet); if(read_length < 0) break; - buf_pos += data_size; + if(got_frame) + { + int data_size = av_samples_get_buffer_size(NULL, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1); + + if(buf_size - buf_pos < data_size) + { + buffer.resize(buf_size + data_size, true); + buf_size += data_size; + } + + if(m_tointerleave) + { + int single_size = data_size / m_codecCtx->channels / frame->nb_samples; + for(int channel = 0; channel < m_codecCtx->channels; channel++) + { + for(int i = 0; i < frame->nb_samples; i++) + { + memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size, + frame->data[channel] + i * single_size, single_size); + } + } + } + else + memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[1], data_size); - // move packet parameters - audio_pkg_data += read_length; - audio_pkg_size -= read_length; + buf_pos += data_size; + } + packet.size -= read_length; + packet.data += read_length; } + packet.data = orig_data; + packet.size = orig_size; + av_free(frame); + return buf_pos; } @@ -133,11 +145,6 @@ void AUD_FFMPEGReader::init() if(!aCodec) AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error); -#ifdef FFMPEG_SAMPLE_FMT_S16P_SUPPORTED - if(m_codecCtx->sample_fmt == AV_SAMPLE_FMT_S16P) - m_codecCtx->request_sample_fmt = AV_SAMPLE_FMT_S16; -#endif - if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0) AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error); @@ -145,8 +152,9 @@ void AUD_FFMPEGReader::init() //dump_format(m_formatCtx, 0, NULL, 0); m_specs.channels = (AUD_Channels) m_codecCtx->channels; + m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt); - switch(m_codecCtx->sample_fmt) + switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt)) { case AV_SAMPLE_FMT_U8: m_convert = AUD_convert_u8_float; @@ -320,7 +328,7 @@ void AUD_FFMPEGReader::seek(int position) if(packet.stream_index == m_stream) { // decode the package - m_pkgbuf_left = decode(&packet, m_pkgbuf); + m_pkgbuf_left = decode(packet, m_pkgbuf); search = false; // check position @@ -405,7 +413,7 @@ void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer) if(packet.stream_index == m_stream) { // decode the package - pkgbuf_pos = decode(&packet, m_pkgbuf); + pkgbuf_pos = decode(packet, m_pkgbuf); // copy to output buffer data_size = AUD_MIN(pkgbuf_pos, left * sample_size); diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h index d5d9fb300ff..377086e2625 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h @@ -112,12 +112,17 @@ private: int64_t m_membufferpos; /** + * Whether the audio data has to be interleaved after reading. + */ + bool m_tointerleave; + + /** * Decodes a packet into the given buffer. * \param packet The AVPacket to decode. * \param buffer The target buffer. * \return The count of read bytes. */ - int decode(AVPacket* packet, AUD_Buffer& buffer); + int decode(AVPacket& packet, AUD_Buffer& buffer); /** * Initializes the object. diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 09db010363e..039fd39fc7d 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -416,7 +416,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup): default=0.0, step=1, precision=4, - subtype = 'DISTANCE' + subtype='DISTANCE', ) cls.aperture_blades = IntProperty( name="Aperture Blades", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 0d1437e13e4..ee33bf6572a 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -219,7 +219,7 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): sub.label(text="Final Render:") sub.prop(rd, "use_persistent_data", text="Persistent Images") - + class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel): bl_label = "OpenGL Render" bl_options = {'DEFAULT_CLOSED'} @@ -230,18 +230,18 @@ class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel): rd = context.scene.render split = layout.split() - + col = split.column() col.prop(rd, "use_antialiasing") sub = col.row() sub.active = rd.use_antialiasing sub.prop(rd, "antialiasing_samples", expand=True) - + col = split.column() col.label(text="Alpha:") col.prop(rd, "alpha_mode", text="") - - + + class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): bl_label = "Layers" bl_options = {'HIDE_HEADER'} @@ -902,8 +902,8 @@ class CyclesTexture_PT_context(CyclesButtonsPanel, Panel): split = layout.split(percentage=0.2) split.label(text="Type:") split.prop(tex, "type", text="") - - + + class CyclesTexture_PT_node(CyclesButtonsPanel, Panel): bl_label = "Node" bl_context = "texture" @@ -932,7 +932,7 @@ class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - + node = context.texture_node mapping = node.texture_mapping @@ -964,7 +964,7 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - + node = context.texture_node mapping = node.color_mapping diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index d10fb99450d..acda90f0b83 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -576,7 +576,7 @@ void BlenderSession::update_status_progress() timestatus += ", " + b_rlay_name; timestatus += " | "; - BLI_timestr(total_time, time_str); + BLI_timestr(total_time, time_str, sizeof(time_str)); timestatus += "Elapsed: " + string(time_str) + " | "; if(substatus.size() > 0) diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index bd4852d08e1..747008fc7c4 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -30,7 +30,7 @@ * todo: clean this up ... */ extern "C" { -void BLI_timestr(double _time, char *str); +void BLI_timestr(double _time, char *str, size_t maxlen); void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr); void BKE_image_user_file_path(void *iuser, void *ima, char *path); unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame); diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index af27b46771c..50fee15c231 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -365,6 +365,45 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed) } } } + + /* remove unused mix closure input when factor is 0.0 or 1.0 */ + if(node->special_type == SHADER_SPECIAL_TYPE_MIX_CLOSURE) { + MixClosureNode *mix = static_cast<MixClosureNode*>(node); + /* Check for closure links and make sure factor link is disconnected */ + if(mix->outputs[0]->links.size() && mix->inputs[1]->link && mix->inputs[2]->link && !mix->inputs[0]->link) { + + /* Factor 0.0 */ + if(mix->inputs[0]->value.x == 0.0f) { + ShaderOutput *output = mix->inputs[1]->link; + vector<ShaderInput*> inputs = mix->outputs[0]->links; + + foreach(ShaderInput *sock, mix->inputs) + if(sock->link) + disconnect(sock); + + foreach(ShaderInput *input, inputs) { + disconnect(input); + if (output) + connect(output, input); + } + } + /* Factor 1.0 */ + else if (mix->inputs[0]->value.x == 1.0f) { + ShaderOutput *output = mix->inputs[2]->link; + vector<ShaderInput*> inputs = mix->outputs[0]->links; + + foreach(ShaderInput *sock, mix->inputs) + if(sock->link) + disconnect(sock); + + foreach(ShaderInput *input, inputs) { + disconnect(input); + if (output) + connect(output, input); + } + } + } + } } } diff --git a/intern/dualcon/intern/octree.h b/intern/dualcon/intern/octree.h index 6cbdc9fb3d8..544048249de 100644 --- a/intern/dualcon/intern/octree.h +++ b/intern/dualcon/intern/octree.h @@ -374,14 +374,14 @@ class Octree /** * Functions to patch rings in a node */ - Node *patch(Node * node, int st[3], int len, PathList * rings); - Node *patchSplit(Node * node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2); - Node *patchSplitSingle(Node * node, int st[3], int len, PathElement * head, int dir, PathList * &nrings1, PathList * &nrings2); - Node *connectFace(Node * node, int st[3], int len, int dir, PathElement * f1, PathElement * f2); - Node *locateCell(InternalNode * node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen); + Node *patch(Node *node, int st[3], int len, PathList * rings); + Node *patchSplit(Node *node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2); + Node *patchSplitSingle(Node *node, int st[3], int len, PathElement *head, int dir, PathList * &nrings1, PathList * &nrings2); + Node *connectFace(Node *node, int st[3], int len, int dir, PathElement * f1, PathElement * f2); + Node *locateCell(InternalNode *node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen); void compressRing(PathElement *& ring); void getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q); - LeafNode *patchAdjacent(InternalNode * node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha); + LeafNode *patchAdjacent(InternalNode *node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha); int findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2); int getSide(PathElement *e, int pos, int dir); int isEqual(PathElement *e1, PathElement *e2); @@ -412,8 +412,8 @@ class Octree /************************************************************************/ void floodFill(); void clearProcessBits(Node *node, int height); - int floodFill(LeafNode * leaf, int st[3], int len, int height, int threshold); - int floodFill(Node * node, int st[3], int len, int height, int threshold); + int floodFill(LeafNode *leaf, int st[3], int len, int height, int threshold); + int floodFill(Node *node, int st[3], int len, int height, int threshold); /** * Write out polygon file @@ -421,9 +421,9 @@ class Octree void writeOut(); void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface); - void generateMinimizer(Node * node, int st[3], int len, int height, int& offset); + void generateMinimizer(Node *node, int st[3], int len, int height, int& offset); void computeMinimizer(const LeafNode * leaf, int st[3], int len, - float rvalue[3]) const; + float rvalue[3]) const; /** * Traversal functions to generate polygon model * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp index 63ce1570eea..4c398ab9cb4 100644 --- a/intern/elbeem/intern/solver_init.cpp +++ b/intern/elbeem/intern/solver_init.cpp @@ -691,7 +691,8 @@ bool LbmFsgrSolver::initializeSolverMemory() calculateMemreqEstimate( mSizex, mSizey, mSizez, mMaxRefine, mFarFieldSize, &memEstFromFunc, &memEstFine, &memreqStr ); - double memLimit; + bool noLimit = false; + double memLimit = 0.; string memLimStr("-"); if(sizeof(void*)==4) { // 32bit system, limit to 2GB @@ -699,8 +700,9 @@ bool LbmFsgrSolver::initializeSolverMemory() memLimStr = string("2GB"); } else { // 64bit, just take 16GB as limit for now... - memLimit = 16.0* 1024.0*1024.0*1024.0; - memLimStr = string("16GB"); + // memLimit = 16.0* 1024.0*1024.0*1024.0; + // memLimStr = string("16GB"); + noLimit = true; } // restrict max. chunk of 1 mem block to 1GB for windos @@ -724,7 +726,7 @@ bool LbmFsgrSolver::initializeSolverMemory() memBlockAllocProblem = true; } - if(memEstFromFunc>memLimit || memBlockAllocProblem) { + if(!noLimit && (memEstFromFunc>memLimit || memBlockAllocProblem)) { sizeReduction *= 0.9; mSizex = (int)(orgSx * sizeReduction); mSizey = (int)(orgSy * sizeReduction); diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index 8663c96a22e..69e2e014761 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -110,6 +110,16 @@ int av_opt_set_double(void *obj, const char *name, double val, int search_flags) #define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT #endif +#if ((LIBAVUTIL_VERSION_MAJOR < 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 54)) +static inline +enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + return sample_fmt; +} +#endif + #if ((LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24) && (LIBAVFORMAT_VERSION_MICRO < 2))) #define avformat_close_input(x) av_close_input_file(*(x)) #endif diff --git a/intern/guardedalloc/MEM_sys_types.h b/intern/guardedalloc/MEM_sys_types.h index 3d43733c569..72563fc988d 100644 --- a/intern/guardedalloc/MEM_sys_types.h +++ b/intern/guardedalloc/MEM_sys_types.h @@ -108,10 +108,6 @@ typedef uint64_t u_int64_t; #include <inttypes.h> #elif defined(FREE_WINDOWS) -#ifndef FREE_WINDOWS64 -/* define htoln here, there must be a syntax error in winsock2.h in MinGW */ -unsigned long __attribute__((__stdcall__)) htonl(unsigned long); -#endif #include <stdint.h> #else @@ -144,4 +140,3 @@ unsigned long __attribute__((__stdcall__)) htonl(unsigned long); #endif #endif /* __MEM_SYS_TYPES_H__ */ - diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index c281a6e7bbb..5680ce79762 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -48,10 +48,12 @@ if(WITH_OPENCOLORIO) list(APPEND INC_SYS ${OPENCOLORIO_INCLUDE_DIRS} + ${GLEW_INCLUDE_PATH} ) list(APPEND SRC ocio_impl.cc + ocio_impl_glsl.cc ) if(WIN32 AND NOT MINGW) diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript index 6e7c467f64f..73a8fd7a2e0 100644 --- a/intern/opencolorio/SConscript +++ b/intern/opencolorio/SConscript @@ -35,10 +35,12 @@ defs = [] if env['WITH_BF_OCIO']: defs.append('WITH_OCIO') incs += ' ' + env['BF_OCIO_INC'] + incs += ' ' + '#/extern/glew/include' if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): incs += ' ' + env['BF_BOOST_INC'] else: sources.remove('ocio_impl.cc') + sources.remove('ocio_impl_glsl.cc') env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185]) diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index d01d8d4c8f4..47c648e9cba 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -380,3 +380,15 @@ void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *) void FallbackImpl::matrixTransformScale(float * , float * , const float *) { } + +void FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ +} + +void FallbackImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) +{ +} + +void FallbackImpl::freeGLState(struct OCIO_GLSLDrawState *state_r) +{ +} diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc index 4f839a61fad..73d8af295f2 100644 --- a/intern/opencolorio/ocio_capi.cc +++ b/intern/opencolorio/ocio_capi.cc @@ -282,3 +282,18 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4 { impl->matrixTransformScale(m44, offset4, scale4f); } + +void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ + impl->setupGLSLDraw(state_r, processor); +} + +void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state) +{ + impl->finishGLSLDraw(state); +} + +void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state) +{ + impl->freeGLState(state); +} diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 19fd8fe643b..3c42e0a1a1e 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -32,6 +32,8 @@ extern "C" { #endif +struct OCIO_GLSLDrawState; + #define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name #define OCIO_ROLE_SCENE_LINEAR "scene_linear" @@ -119,6 +121,10 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4); +void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); +void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state); +void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state); + #ifdef __cplusplus } #endif diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index b073a038f0d..8803814ce3f 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -26,8 +26,16 @@ */ #include <iostream> +#include <sstream> #include <string.h> +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/glew.h> +#endif + #include <OpenColorIO/OpenColorIO.h> using namespace OCIO_NAMESPACE; @@ -50,6 +58,8 @@ using namespace OCIO_NAMESPACE; #define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type() #define MEM_DELETE(what, type) if(what) { ((type*)(what))->~type(); MEM_freeN(what); } (void)0 +static const int LUT3D_EDGE_SIZE = 32; + static void OCIO_reportError(const char *err) { std::cerr << "OpenColorIO Error: " << err << std::endl; @@ -541,3 +551,228 @@ void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *s { MatrixTransform::Scale(m44, offset4, scale4f); } + +/* **** OpenGL drawing routines using GLSL for color space transform ***** */ + +/* Some of the GLSL transform related functions below are adopted from + * ociodisplay utility of OpenColorIO project which are originally + * + * Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved. + */ + +typedef struct OCIO_GLSLDrawState { + bool lut3d_texture_allocated; /* boolean flag indicating whether + * lut texture is allocated + */ + + GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ + + float *lut3d; /* 3D LUT table */ + + /* Cache */ + std::string lut3dcacheid; + std::string shadercacheid; + + /* GLSL stuff */ + GLuint fragShader; + GLuint program; + + /* Previous OpenGL state. */ + GLint last_texture, last_texture_unit; +} OCIO_GLSLDrawState; + +static const char * g_fragShaderText = "" +"\n" +"uniform sampler2D tex1;\n" +"uniform sampler3D tex2;\n" +"\n" +"void main()\n" +"{\n" +" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n" +" gl_FragColor = OCIODisplay(col, tex2);\n" +"}\n"; + +static GLuint compileShaderText(GLenum shaderType, const char *text) +{ + GLuint shader; + GLint stat; + + shader = glCreateShader(shaderType); + glShaderSource(shader, 1, (const GLchar **) &text, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); + + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog(shader, 1000, &len, log); + return 0; + } + + return shader; +} + +static GLuint linkShaders(GLuint fragShader) +{ + if (!fragShader) + return 0; + + GLuint program = glCreateProgram(); + + if (fragShader) + glAttachShader(program, fragShader); + + glLinkProgram(program); + + /* check link */ + { + GLint stat; + glGetProgramiv(program, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog(program, 1000, &len, log); + fprintf(stderr, "Shader link error:\n%s\n", log); + return 0; + } + } + + return program; +} + +static OCIO_GLSLDrawState *allocateOpenGLState(void) +{ + OCIO_GLSLDrawState *state; + + /* Allocate memory for state. */ + state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState), + "OCIO OpenGL State struct"); + + /* Call constructors on new memory. */ + new (&state->lut3dcacheid) std::string(""); + new (&state->shadercacheid) std::string(""); + + return state; +} + +/* Ensure LUT texture and array are allocated */ +static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state) +{ + int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; + + if (state->lut3d_texture_allocated) + return; + + glGenTextures(1, &state->lut3d_texture); + + state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT"); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + 0, GL_RGB,GL_FLOAT, &state->lut3d); + + state->lut3d_texture_allocated = true; +} + +/** + * Setup OpenGL contexts for a transform defined by processor using GLSL + * All LUT allocating baking and shader compilation happens here. + * + * Once this function is called, callee could start drawing images + * using regular 2D texture. + * + * When all drawing is finished, finishGLSLDraw shall be called to + * restore OpenGL context to it's pre-GLSL draw state. + */ +void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ + ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor; + + /* Create state if needed. */ + OCIO_GLSLDrawState *state; + if (!*state_r) + *state_r = allocateOpenGLState(); + state = *state_r; + + glGetIntegerv(GL_TEXTURE_2D, &state->last_texture); + glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); + + ensureLUT3DAllocated(state); + + /* Step 1: Create a GPU Shader Description */ + GpuShaderDesc shaderDesc; + shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0); + shaderDesc.setFunctionName("OCIODisplay"); + shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); + + /* Step 2: Compute the 3D LUT */ + std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc); + if (lut3dCacheID != state->lut3dcacheid) { + state->lut3dcacheid = lut3dCacheID; + ocio_processor->getGpuLut3D(state->lut3d, shaderDesc); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + GL_RGB, GL_FLOAT, state->lut3d); + } + + /* Step 3: Compute the Shader */ + std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc); + if (state->program == 0 || shaderCacheID != state->shadercacheid) { + state->shadercacheid = shaderCacheID; + + std::ostringstream os; + os << ocio_processor->getGpuShaderText(shaderDesc) << "\n"; + os << g_fragShaderText; + + if (state->fragShader) + glDeleteShader(state->fragShader); + state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str()); + + if (state->program) + glDeleteProgram(state->program); + + state->program = linkShaders(state->fragShader); + } + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + + glActiveTexture(GL_TEXTURE0); + + glUseProgram(state->program); + glUniform1i(glGetUniformLocation(state->program, "tex1"), 0); + glUniform1i(glGetUniformLocation(state->program, "tex2"), 1); +} + +void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) +{ + glActiveTexture(state->last_texture_unit); + glBindTexture(GL_TEXTURE_2D, state->last_texture); + glUseProgram(0); +} + +void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state) +{ + using std::string; + + if (state->lut3d_texture_allocated) + glDeleteTextures(1, &state->lut3d_texture); + + if (state->lut3d) + MEM_freeN(state->lut3d); + + state->lut3dcacheid.~string(); + state->shadercacheid.~string(); + + MEM_freeN(state); +} diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h index b6bbc912e5b..2a1f88be5f4 100644 --- a/intern/opencolorio/ocio_impl.h +++ b/intern/opencolorio/ocio_impl.h @@ -95,6 +95,10 @@ public: virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0; virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0; + + virtual void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) = 0; + virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0; + virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0; }; class FallbackImpl : public IOCIOImpl { @@ -164,6 +168,10 @@ public: void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void matrixTransformScale(float * m44, float * offset4, const float * scale4); + + void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); + void finishGLSLDraw(struct OCIO_GLSLDrawState *state); + void freeGLState(struct OCIO_GLSLDrawState *state_r); }; #ifdef WITH_OCIO @@ -234,6 +242,10 @@ public: void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void matrixTransformScale(float * m44, float * offset4, const float * scale4); + + void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); + void finishGLSLDraw(struct OCIO_GLSLDrawState *state); + void freeGLState(struct OCIO_GLSLDrawState *state_r); }; #endif diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc new file mode 100644 index 00000000000..c79593779cf --- /dev/null +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -0,0 +1,274 @@ +/* + * Adapted from OpenColorIO with this license: + * + * Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Modifications Copyright 2013, Blender Foundation. + * + * Contributor(s): Sergey Sharybin + * + */ + +#include <sstream> +#include <string.h> + +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/glew.h> +#endif + +#include <OpenColorIO/OpenColorIO.h> + +using namespace OCIO_NAMESPACE; + +#include "MEM_guardedalloc.h" + +#include "ocio_impl.h" + +static const int LUT3D_EDGE_SIZE = 32; + + +/* **** OpenGL drawing routines using GLSL for color space transform ***** */ + +typedef struct OCIO_GLSLDrawState { + bool lut3d_texture_allocated; /* boolean flag indicating whether + * lut texture is allocated + */ + + GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ + + float *lut3d; /* 3D LUT table */ + + /* Cache */ + std::string lut3dcacheid; + std::string shadercacheid; + + /* GLSL stuff */ + GLuint fragShader; + GLuint program; + + /* Previous OpenGL state. */ + GLint last_texture, last_texture_unit; +} OCIO_GLSLDrawState; + +static const char * g_fragShaderText = "" +"\n" +"uniform sampler2D tex1;\n" +"uniform sampler3D tex2;\n" +"\n" +"void main()\n" +"{\n" +" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n" +" gl_FragColor = OCIODisplay(col, tex2);\n" +"}\n"; + +static GLuint compileShaderText(GLenum shaderType, const char *text) +{ + GLuint shader; + GLint stat; + + shader = glCreateShader(shaderType); + glShaderSource(shader, 1, (const GLchar **) &text, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); + + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog(shader, 1000, &len, log); + return 0; + } + + return shader; +} + +static GLuint linkShaders(GLuint fragShader) +{ + if (!fragShader) + return 0; + + GLuint program = glCreateProgram(); + + if (fragShader) + glAttachShader(program, fragShader); + + glLinkProgram(program); + + /* check link */ + { + GLint stat; + glGetProgramiv(program, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog(program, 1000, &len, log); + fprintf(stderr, "Shader link error:\n%s\n", log); + return 0; + } + } + + return program; +} + +static OCIO_GLSLDrawState *allocateOpenGLState(void) +{ + OCIO_GLSLDrawState *state; + + /* Allocate memory for state. */ + state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState), + "OCIO OpenGL State struct"); + + /* Call constructors on new memory. */ + new (&state->lut3dcacheid) std::string(""); + new (&state->shadercacheid) std::string(""); + + return state; +} + +/* Ensure LUT texture and array are allocated */ +static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state) +{ + int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; + + if (state->lut3d_texture_allocated) + return; + + glGenTextures(1, &state->lut3d_texture); + + state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT"); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + 0, GL_RGB,GL_FLOAT, &state->lut3d); + + state->lut3d_texture_allocated = true; +} + +/** + * Setup OpenGL contexts for a transform defined by processor using GLSL + * All LUT allocating baking and shader compilation happens here. + * + * Once this function is called, callee could start drawing images + * using regular 2D texture. + * + * When all drawing is finished, finishGLSLDraw shall be called to + * restore OpenGL context to it's pre-GLSL draw state. + */ +void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ + ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor; + + /* Create state if needed. */ + OCIO_GLSLDrawState *state; + if (!*state_r) + *state_r = allocateOpenGLState(); + state = *state_r; + + glGetIntegerv(GL_TEXTURE_2D, &state->last_texture); + glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); + + ensureLUT3DAllocated(state); + + /* Step 1: Create a GPU Shader Description */ + GpuShaderDesc shaderDesc; + shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0); + shaderDesc.setFunctionName("OCIODisplay"); + shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); + + /* Step 2: Compute the 3D LUT */ + std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc); + if (lut3dCacheID != state->lut3dcacheid) { + state->lut3dcacheid = lut3dCacheID; + ocio_processor->getGpuLut3D(state->lut3d, shaderDesc); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + GL_RGB, GL_FLOAT, state->lut3d); + } + + /* Step 3: Compute the Shader */ + std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc); + if (state->program == 0 || shaderCacheID != state->shadercacheid) { + state->shadercacheid = shaderCacheID; + + std::ostringstream os; + os << ocio_processor->getGpuShaderText(shaderDesc) << "\n"; + os << g_fragShaderText; + + if (state->fragShader) + glDeleteShader(state->fragShader); + state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str()); + + if (state->program) + glDeleteProgram(state->program); + + state->program = linkShaders(state->fragShader); + } + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + + glActiveTexture(GL_TEXTURE0); + + glUseProgram(state->program); + glUniform1i(glGetUniformLocation(state->program, "tex1"), 0); + glUniform1i(glGetUniformLocation(state->program, "tex2"), 1); +} + +void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) +{ + glActiveTexture(state->last_texture_unit); + glBindTexture(GL_TEXTURE_2D, state->last_texture); + glUseProgram(0); +} + +void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state) +{ + using std::string; + + if (state->lut3d_texture_allocated) + glDeleteTextures(1, &state->lut3d_texture); + + if (state->lut3d) + MEM_freeN(state->lut3d); + + state->lut3dcacheid.~string(); + state->shadercacheid.~string(); + + MEM_freeN(state); +} diff --git a/intern/opennl/superlu/superlu_sys_types.h b/intern/opennl/superlu/superlu_sys_types.h index 80d3da4d243..5685b34f1f4 100644 --- a/intern/opennl/superlu/superlu_sys_types.h +++ b/intern/opennl/superlu/superlu_sys_types.h @@ -98,8 +98,6 @@ typedef unsigned long uintptr_t; #include <inttypes.h> #elif defined(FREE_WINDOWS) -/* define htoln here, there must be a syntax error in winsock2.h in MinGW */ -unsigned long __attribute__((__stdcall__)) htonl(unsigned long); #include <stdint.h> #else diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c index 3d7fb11309a..2ae261b44a8 100644 --- a/intern/utfconv/utf_winfunc.c +++ b/intern/utfconv/utf_winfunc.c @@ -28,12 +28,13 @@ #endif #include "utf_winfunc.h" +#include "utfconv.h" #include <io.h> #include <windows.h> #include <wchar.h> -FILE * ufopen(const char * filename, const char * mode) +FILE *ufopen(const char *filename, const char *mode) { FILE *f = NULL; UTF16_ENCODE(filename); @@ -119,7 +120,7 @@ int umkdir(const char *pathname) return r ? 0 : -1; } -char * u_alloc_getenv(const char *varname) +char *u_alloc_getenv(const char *varname) { char * r = 0; wchar_t * str; diff --git a/intern/utfconv/utf_winfunc.h b/intern/utfconv/utf_winfunc.h index 45f6844af5a..8dd77275dcb 100644 --- a/intern/utfconv/utf_winfunc.h +++ b/intern/utfconv/utf_winfunc.h @@ -23,22 +23,26 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef __UTF_WINFUNC_H__ +#define __UTF_WINFUNC_H__ + #ifndef WIN32 # error "This file can only compile on windows" #endif -#include "utfconv.h" #include <stdio.h> -FILE * ufopen(const char * filename, const char * mode); +FILE *ufopen(const char * filename, const char * mode); int uopen(const char *filename, int oflag, int pmode); int uaccess(const char *filename, int mode); -int urename(const char *oldname, const char *newname ); +int urename(const char *oldname, const char *newname); -char * u_alloc_getenv(const char *varname); +char *u_alloc_getenv(const char *varname); void u_free_getenv(char *val); -int uput_getenv(const char *varname, char * value, size_t buffsize); +int uput_getenv(const char *varname, char *value, size_t buffsize); int uputenv(const char *name, const char *value); int umkdir(const char *pathname); + +#endif /* __UTF_WINFUNC_H__ */ diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h index ada85e274e3..f00f4aeef27 100644 --- a/intern/utfconv/utfconv.h +++ b/intern/utfconv/utfconv.h @@ -23,12 +23,13 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef __UTFCONV_H__ +#define __UTFCONV_H__ + #include <wchar.h> #include <stdio.h> #include <stdlib.h> - - #ifdef __cplusplus extern "C" { #endif @@ -100,3 +101,5 @@ wchar_t *alloc_utf16_from_8(const char *in8, size_t add); #ifdef __cplusplus } #endif + +#endif /* __UTFCONV_H__ */ |