/** * Dump images of current draw drawable/window. */ static void dumpDrawableImages(JSONWriter &json, Context &context) { GLint width, height; if (!getDrawableBounds(&width, &height)) { return; } GLint draw_buffer = GL_NONE; if (context.ES) { draw_buffer = GL_BACK; } else { glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); glReadBuffer(draw_buffer); } if (draw_buffer != GL_NONE) { GLint read_buffer = GL_NONE; if (!context.ES) { glGetIntegerv(GL_READ_BUFFER, &read_buffer); } GLint alpha_bits = 0; #if 0 // XXX: Ignore alpha until we are able to match the traced visual glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); #endif GLenum format = alpha_bits ? GL_RGBA : GL_RGB; json.beginMember(enumToString(draw_buffer)); dumpReadBufferImage(json, width, height, format); json.endMember(); if (!context.ES) { glReadBuffer(read_buffer); } } if (!context.ES) { GLint depth_bits = 0; glGetIntegerv(GL_DEPTH_BITS, &depth_bits); if (depth_bits) { json.beginMember("GL_DEPTH_COMPONENT"); dumpReadBufferImage(json, width, height, GL_DEPTH_COMPONENT); json.endMember(); } GLint stencil_bits = 0; glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); if (stencil_bits) { json.beginMember("GL_STENCIL_INDEX"); dumpReadBufferImage(json, width, height, GL_STENCIL_INDEX); json.endMember(); } } }
static inline void dumpArbProgram(JSONWriter &json, GLenum target) { if (!glIsEnabled(target)) { return; } GLint program_length = 0; glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length); if (!program_length) { return; } GLchar *source = new GLchar[program_length + 1]; source[0] = 0; glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source); source[program_length] = 0; json.beginMember(enumToString(target)); json.writeString(source); json.endMember(); delete [] source; }
void dumpTextures(JSONWriter &json, IDirect3DDevice9 *pDevice) { HRESULT hr; json.beginMember("textures"); json.beginObject(); for (DWORD Stage = 0; Stage < 16; ++Stage) { com_ptr<IDirect3DBaseTexture9> pTexture; hr = pDevice->GetTexture(Stage, &pTexture); if (FAILED(hr)) { continue; } if (!pTexture) { continue; } D3DRESOURCETYPE Type = pTexture->GetType(); DWORD NumFaces = Type == D3DRTYPE_CUBETEXTURE ? 6 : 1; DWORD NumLevels = pTexture->GetLevelCount(); for (DWORD Face = 0; Face < NumFaces; ++Face) { for (DWORD Level = 0; Level < NumLevels; ++Level) { image::Image *image; image = getTextureImage(pDevice, pTexture, static_cast<D3DCUBEMAP_FACES>(Face), Level); if (image) { char label[128]; if (Type == D3DRTYPE_CUBETEXTURE) { _snprintf(label, sizeof label, "PS_RESOURCE_%lu_FACE_%lu_LEVEL_%lu", Stage, Face, Level); } else { _snprintf(label, sizeof label, "PS_RESOURCE_%lu_LEVEL_%lu", Stage, Level); } json.beginMember(label); json.writeImage(image); json.endMember(); // PS_RESOURCE_* } } } } json.endObject(); json.endMember(); // textures }
static void dumpBlendState(JSONWriter &json, ID3D11DeviceContext *pDeviceContext) { com_ptr<ID3D11BlendState> pBlendState; FLOAT BlendFactor[4]; UINT SampleMask; pDeviceContext->OMGetBlendState(&pBlendState, BlendFactor, &SampleMask); json.beginMember("BlendState"); dumpStateObjectDesc(json, pBlendState); json.endMember(); // BlendState json.beginMember("BlendFactor"); json.beginArray(); json.writeFloat(BlendFactor[0]); json.writeFloat(BlendFactor[1]); json.writeFloat(BlendFactor[2]); json.writeFloat(BlendFactor[3]); json.endArray(); json.endMember(); // BlendFactor json.writeIntMember("SampleMask", SampleMask); }
static void CheckTlbPath(JSONWriter& aJson, const nsAString& aTypelibPath) { const nsString& flatPath = PromiseFlatString(aTypelibPath); DWORD bufCharLen = ExpandEnvironmentStrings(flatPath.get(), nullptr, 0); auto buf = MakeUnique<WCHAR[]>(bufCharLen); if (!ExpandEnvironmentStrings(flatPath.get(), buf.get(), bufCharLen)) { return; } // See whether this tlb can actually be loaded RefPtr<ITypeLib> typeLib; HRESULT hr = LoadTypeLibEx(buf.get(), REGKIND_NONE, getter_AddRefs(typeLib)); nsPrintfCString loadResult("0x%08X", hr); aJson.StringProperty("LoadResult", loadResult.get()); }
void DeprecationReportBody::ToJSON(JSONWriter& aWriter) const { aWriter.StringProperty("id", NS_ConvertUTF16toUTF8(mId).get()); // TODO: anticipatedRemoval? https://github.com/w3c/reporting/issues/132 aWriter.StringProperty("message", NS_ConvertUTF16toUTF8(mMessage).get()); if (mSourceFile.IsEmpty()) { aWriter.NullProperty("sourceFile"); } else { aWriter.StringProperty("sourceFile", NS_ConvertUTF16toUTF8(mSourceFile).get()); } if (mLineNumber.IsNull()) { aWriter.NullProperty("lineNumber"); } else { aWriter.IntProperty("lineNumber", mLineNumber.Value()); } if (mColumnNumber.IsNull()) { aWriter.NullProperty("columnNumber"); } else { aWriter.IntProperty("columnNumber", mColumnNumber.Value()); } }
/** * Dump images of current draw drawable/window. */ static void dumpDrawableImages(JSONWriter &json) { GLint width, height; if (!getDrawableBounds(&width, &height)) { return; } GLint draw_buffer = GL_NONE; glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); glReadBuffer(draw_buffer); if (draw_buffer != GL_NONE) { GLint read_buffer = GL_NONE; glGetIntegerv(GL_READ_BUFFER, &read_buffer); GLint alpha_bits = 0; glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); GLenum format = alpha_bits ? GL_RGBA : GL_RGB; json.beginMember(enumToString(draw_buffer)); dumpReadBufferImage(json, width, height, format); json.endMember(); glReadBuffer(read_buffer); } GLint depth_bits = 0; glGetIntegerv(GL_DEPTH_BITS, &depth_bits); if (depth_bits) { json.beginMember("GL_DEPTH_COMPONENT"); dumpReadBufferImage(json, width, height, GL_DEPTH_COMPONENT); json.endMember(); } GLint stencil_bits = 0; glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); if (stencil_bits) { json.beginMember("GL_STENCIL_INDEX"); dumpReadBufferImage(json, width, height, GL_STENCIL_INDEX); json.endMember(); } }
bool JSONObject::serialize(JSONWriter &writer){ if (_properties.size() > 0){ writer.writeStartObject(); bool wroteOne = false; for (auto iter = _properties.begin(); iter != _properties.end(); iter++){ if (iter->second && (*(iter->second)).hasValue()){ if (wroteOne){ writer.writeRaw(","); } writer.writeNext(); writer.writeKey(iter->first); writer.writeRaw(": "); (*(iter->second)).serialize(writer); wroteOne = true; } } writer.writeEndObject(); return true; } return false; }
/** * Dump the image of the currently bound read buffer. */ static inline void dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, GLint internalFormat = GL_NONE) { GLint channels = _gl_format_channels(format); if (internalFormat == GL_NONE) { internalFormat = format; } Context context; json.beginObject(); // Tell the GUI this is no ordinary object, but an image json.writeStringMember("__class__", "image"); json.writeNumberMember("__width__", width); json.writeNumberMember("__height__", height); json.writeNumberMember("__depth__", 1); json.writeStringMember("__format__", enumToString(internalFormat)); // Hardcoded for now, but we could chose types more adequate to the // texture internal format json.writeStringMember("__type__", "uint8"); json.writeBoolMember("__normalized__", true); json.writeNumberMember("__channels__", channels); GLenum type = GL_UNSIGNED_BYTE; #if DEPTH_AS_RGBA if (format == GL_DEPTH_COMPONENT) { type = GL_UNSIGNED_INT; channels = 4; } #endif GLubyte *pixels = new GLubyte[width*height*channels]; // TODO: reset imaging state too context.resetPixelPackState(); glReadPixels(0, 0, width, height, format, type, pixels); context.restorePixelPackState(); json.beginMember("__data__"); char *pngBuffer; int pngBufferSize; image::writePixelsToBuffer(pixels, width, height, channels, true, &pngBuffer, &pngBufferSize); //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels) // <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize; json.writeBase64(pngBuffer, pngBufferSize); free(pngBuffer); json.endMember(); // __data__ delete [] pixels; json.endObject(); }
static inline void dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint level) { ImageDesc desc; if (!getActiveTextureLevelDesc(context, target, level, desc)) { return; } char label[512]; GLint active_texture = GL_TEXTURE0; glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); snprintf(label, sizeof label, "%s, %s, level = %d", enumToString(active_texture), enumToString(target), level); json.beginMember(label); json.beginObject(); GLuint channels; GLenum format; if (!context.ES && isDepthFormat(desc.internalFormat)) { format = GL_DEPTH_COMPONENT; channels = 1; } else { format = GL_RGBA; channels = 4; } // Tell the GUI this is no ordinary object, but an image json.writeStringMember("__class__", "image"); json.writeNumberMember("__width__", desc.width); json.writeNumberMember("__height__", desc.height); json.writeNumberMember("__depth__", desc.depth); json.writeStringMember("__format__", enumToString(desc.internalFormat)); // Hardcoded for now, but we could chose types more adequate to the // texture internal format json.writeStringMember("__type__", "uint8"); json.writeBoolMember("__normalized__", true); json.writeNumberMember("__channels__", channels); GLubyte *pixels = new GLubyte[desc.depth*desc.width*desc.height*channels]; context.resetPixelPackState(); if (context.ES) { getTexImageOES(target, level, desc, pixels); } else { glGetTexImage(target, level, format, GL_UNSIGNED_BYTE, pixels); } context.restorePixelPackState(); json.beginMember("__data__"); char *pngBuffer; int pngBufferSize; image::writePixelsToBuffer(pixels, desc.width, desc.height, channels, true, &pngBuffer, &pngBufferSize); json.writeBase64(pngBuffer, pngBufferSize); free(pngBuffer); json.endMember(); // __data__ delete [] pixels; json.endObject(); }
void dumpFramebuffer(JSONWriter &json, Context &context) { json.beginMember("framebuffer"); json.beginObject(); GLint boundDrawFbo = 0, boundReadFbo = 0; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo); glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo); if (!boundDrawFbo) { dumpDrawableImages(json, context); } else if (context.ES) { dumpFramebufferAttachments(json, context, GL_FRAMEBUFFER); } else { GLint colorRb = 0, stencilRb = 0, depthRb = 0; GLint draw_buffer0 = GL_NONE; glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer0); bool multisample = false; GLint boundRb = 0; glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb); GLint object_type; glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type); if (object_type == GL_RENDERBUFFER) { glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &colorRb); glBindRenderbuffer(GL_RENDERBUFFER, colorRb); GLint samples = 0; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); if (samples) { multisample = true; } } glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type); if (object_type == GL_RENDERBUFFER) { glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthRb); glBindRenderbuffer(GL_RENDERBUFFER, depthRb); GLint samples = 0; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); if (samples) { multisample = true; } } glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type); if (object_type == GL_RENDERBUFFER) { glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &stencilRb); glBindRenderbuffer(GL_RENDERBUFFER, stencilRb); GLint samples = 0; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); if (samples) { multisample = true; } } glBindRenderbuffer(GL_RENDERBUFFER, boundRb); GLuint rbs[3]; GLint numRbs = 0; GLuint fboCopy = 0; if (multisample) { // glReadPixels doesnt support multisampled buffers so we need // to blit the fbo to a temporary one fboCopy = downsampledFramebuffer(context, boundDrawFbo, draw_buffer0, colorRb, depthRb, stencilRb, rbs, &numRbs); } dumpFramebufferAttachments(json, context, GL_DRAW_FRAMEBUFFER); if (multisample) { glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb); glDeleteRenderbuffers(numRbs, rbs); glDeleteFramebuffers(1, &fboCopy); } glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo); } json.endObject(); json.endMember(); // framebuffer }
/** * Dump the image of the currently bound read buffer. */ static inline void dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format) { GLint channels = __gl_format_channels(format); json.beginObject(); // Tell the GUI this is no ordinary object, but an image json.writeStringMember("__class__", "image"); json.writeNumberMember("__width__", width); json.writeNumberMember("__height__", height); json.writeNumberMember("__depth__", 1); // Hardcoded for now, but we could chose types more adequate to the // texture internal format json.writeStringMember("__type__", "uint8"); json.writeBoolMember("__normalized__", true); json.writeNumberMember("__channels__", channels); GLubyte *pixels = new GLubyte[width*height*channels]; resetPixelPackState(); glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels); restorePixelPackState(); json.beginMember("__data__"); char *pngBuffer; int pngBufferSize; Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize); //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels) // <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize; json.writeBase64(pngBuffer, pngBufferSize); free(pngBuffer); json.endMember(); // __data__ delete [] pixels; json.endObject(); }
bool serialize(JSONWriter &writer) { writer.writeRaw("null"); return true; }
void dumpShadersUniforms(JSONWriter &json, Context &context) { GLint pipeline = 0; GLint vertex_program = 0; GLint fragment_program = 0; GLint geometry_program = 0; GLint tess_control_program = 0; GLint tess_evaluation_program = 0; GLint compute_program = 0; if (!context.ES) { glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING, &pipeline); if (pipeline) { glGetProgramPipelineiv(pipeline, GL_VERTEX_SHADER, &vertex_program); glGetProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, &fragment_program); glGetProgramPipelineiv(pipeline, GL_GEOMETRY_SHADER, &geometry_program); glGetProgramPipelineiv(pipeline, GL_TESS_CONTROL_SHADER, &tess_control_program); glGetProgramPipelineiv(pipeline, GL_TESS_EVALUATION_SHADER, &tess_evaluation_program); glGetProgramPipelineiv(pipeline, GL_COMPUTE_SHADER, &compute_program); } } GLint program = 0; if (!pipeline) { glGetIntegerv(GL_CURRENT_PROGRAM, &program); } json.beginMember("shaders"); json.beginObject(); if (pipeline) { dumpProgram(json, vertex_program); dumpProgram(json, fragment_program); dumpProgram(json, geometry_program); dumpProgram(json, tess_control_program); dumpProgram(json, tess_evaluation_program); dumpProgram(json, compute_program); } else if (program) { dumpProgram(json, program); } else { dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB); dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB); } json.endObject(); json.endMember(); // shaders json.beginMember("uniforms"); json.beginObject(); if (pipeline) { dumpProgramUniformsStage(json, vertex_program, "GL_VERTEX_SHADER"); dumpProgramUniformsStage(json, fragment_program, "GL_FRAGMENT_SHADER"); dumpProgramUniformsStage(json, geometry_program, "GL_GEOMETRY_SHADER"); dumpProgramUniformsStage(json, tess_control_program, "GL_TESS_CONTROL_SHADER"); dumpProgramUniformsStage(json, tess_evaluation_program, "GL_TESS_EVALUATION_SHADER"); dumpProgramUniformsStage(json, compute_program, "GL_COMPUTE_SHADER"); } else if (program) { dumpProgramUniforms(json, program); } else { dumpArbProgramUniforms(json, GL_FRAGMENT_PROGRAM_ARB, "fp."); dumpArbProgramUniforms(json, GL_VERTEX_PROGRAM_ARB, "vp."); } json.endObject(); json.endMember(); // uniforms json.beginMember("buffers"); json.beginObject(); if (program) { dumpTransformFeedback(json, program); } json.endObject(); json.endMember(); // buffers }
static inline void dumpArbProgramUniforms(JSONWriter &json, GLenum target, const char *prefix) { if (!glIsEnabled(target)) { return; } GLint program_parameters = 0; glGetProgramivARB(target, GL_PROGRAM_PARAMETERS_ARB, &program_parameters); if (!program_parameters) { return; } GLint max_program_local_parameters = 0; glGetProgramivARB(target, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &max_program_local_parameters); for (GLint index = 0; index < max_program_local_parameters; ++index) { GLdouble params[4] = {0, 0, 0, 0}; glGetProgramLocalParameterdvARB(target, index, params); if (!params[0] && !params[1] && !params[2] && !params[3]) { continue; } char name[256]; snprintf(name, sizeof name, "%sprogram.local[%i]", prefix, index); json.beginMember(name); json.beginArray(); json.writeFloat(params[0]); json.writeFloat(params[1]); json.writeFloat(params[2]); json.writeFloat(params[3]); json.endArray(); json.endMember(); } GLint max_program_env_parameters = 0; glGetProgramivARB(target, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &max_program_env_parameters); for (GLint index = 0; index < max_program_env_parameters; ++index) { GLdouble params[4] = {0, 0, 0, 0}; glGetProgramEnvParameterdvARB(target, index, params); if (!params[0] && !params[1] && !params[2] && !params[3]) { continue; } char name[256]; snprintf(name, sizeof name, "%sprogram.env[%i]", prefix, index); json.beginMember(name); json.beginArray(); json.writeFloat(params[0]); json.writeFloat(params[1]); json.writeFloat(params[2]); json.writeFloat(params[3]); json.endArray(); json.endMember(); } }
static inline void dumpTransformFeedback(JSONWriter &json, GLint program) { GLint transform_feedback_varyings = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varyings); if (!transform_feedback_varyings) { return; } GLint max_name_length = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_name_length); std::vector<GLchar> name(max_name_length); GLint buffer_mode = GL_INTERLEAVED_ATTRIBS; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &buffer_mode); std::vector<TransformFeedbackAttrib> attribs(transform_feedback_varyings); // Calculate the offsets and strides of each attribute according to // the value of GL_TRANSFORM_FEEDBACK_BUFFER_MODE GLsizei cum_attrib_offset = 0; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; GLsizei length = 0; GLsizei size = 0; GLenum type = GL_NONE; glGetTransformFeedbackVarying(program, slot, max_name_length, &length, &size, &type, &name[0]); attrib.name = &name[0]; const AttribDesc & desc = attrib.desc = AttribDesc(type, size); if (!desc) { return; } attrib.size = desc.arrayStride; switch (buffer_mode) { case GL_INTERLEAVED_ATTRIBS: attrib.offset = cum_attrib_offset; break; case GL_SEPARATE_ATTRIBS: attrib.offset = 0; attrib.stride = desc.arrayStride; break; default: assert(0); attrib.offset = 0; attrib.stride = 0; } cum_attrib_offset += desc.arrayStride; } if (buffer_mode == GL_INTERLEAVED_ATTRIBS) { for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.stride = cum_attrib_offset; } } GLint previous_tbo = 0; glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &previous_tbo); // Map the buffers and calculate how many vertices can they hold // XXX: We currently limit to 1024, or things can get significantly slow. unsigned numVertices = 16*1024; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.map = NULL; if (slot == 0 || buffer_mode != GL_INTERLEAVED_ATTRIBS) { GLint tbo = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, slot, &tbo); if (!tbo) { numVertices = 0; continue; } GLint start = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_START, slot, &start); GLint size = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, slot, &size); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo); if (size == 0) { glGetBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &size); assert(size >= start); size -= start; } unsigned numAttribVertices = calcNumElements(size, attrib.offset, attrib.size, attrib.stride); numVertices = std::min(numVertices, numAttribVertices); attrib.map = (const GLbyte *)glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY) + start; } else { attrib.map = attribs[0].map; } } // Actually dump the vertices json.beginMember("GL_TRANSFORM_FEEDBACK"); json.beginArray(); for (unsigned vertex = 0; vertex < numVertices; ++vertex) { json.beginObject(); for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; if (!attrib.map) { continue; } const AttribDesc & desc = attrib.desc; assert(desc); const GLbyte *vertex_data = attrib.map + attrib.stride*vertex + attrib.offset; dumpAttribArray(json, attrib.name, desc, vertex_data); } json.endObject(); } json.endArray(); json.endMember(); // Unmap the buffers for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; if (slot == 0 || buffer_mode != GL_INTERLEAVED_ATTRIBS) { if (!attrib.map) { continue; } GLint tbo = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, slot, &tbo); assert(tbo); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo); glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); } } glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, previous_tbo); }
static void dumpUniform(JSONWriter &json, GLint program, const AttribDesc & desc, const GLchar *name) { if (desc.elemType == GL_NONE) { return; } union { GLfloat fvalues[4*4]; GLdouble dvalues[4*4]; GLint ivalues[4*4]; GLuint uivalues[4*4]; GLbyte data[4*4*4]; } u; GLint i; std::string qualifiedName = resolveUniformName(name, desc.size); json.beginMember(qualifiedName); if (desc.size > 1) { json.beginArray(); } for (i = 0; i < desc.size; ++i) { std::stringstream ss; ss << qualifiedName; if (desc.size > 1) { ss << '[' << i << ']'; } std::string elemName = ss.str(); GLint location = glGetUniformLocation(program, elemName.c_str()); assert(location != -1); if (location == -1) { continue; } switch (desc.elemType) { case GL_FLOAT: glGetUniformfv(program, location, u.fvalues); break; case GL_DOUBLE: glGetUniformdv(program, location, u.dvalues); break; case GL_INT: glGetUniformiv(program, location, u.ivalues); break; case GL_UNSIGNED_INT: glGetUniformuiv(program, location, u.uivalues); break; case GL_BOOL: glGetUniformiv(program, location, u.ivalues); break; default: assert(0); break; } dumpAttrib(json, desc, u.data); } if (desc.size > 1) { json.endArray(); } json.endMember(); }
explicit JSONSchemaWriter(JSONWriter& aWriter) : mWriter(aWriter) , mIndex(0) { aWriter.StartObjectProperty("schema"); }
static void dumpShaderResourceViewImage(JSONWriter &json, ID3D10Device *pDevice, ID3D10ShaderResourceView *pShaderResourceView, const char *shader, UINT stage) { if (!pShaderResourceView) { return; } com_ptr<ID3D10Resource> pResource; pShaderResourceView->GetResource(&pResource); assert(pResource); D3D10_SHADER_RESOURCE_VIEW_DESC Desc; pShaderResourceView->GetDesc(&Desc); UINT MipSlice = 0; UINT FirstArraySlice = 0; UINT ArraySize = 1; switch (Desc.ViewDimension) { case D3D10_SRV_DIMENSION_BUFFER: break; case D3D10_SRV_DIMENSION_TEXTURE1D: MipSlice = Desc.Texture1D.MostDetailedMip; break; case D3D10_SRV_DIMENSION_TEXTURE1DARRAY: MipSlice = Desc.Texture1DArray.MostDetailedMip; FirstArraySlice = Desc.Texture1DArray.FirstArraySlice; ArraySize = Desc.Texture1DArray.ArraySize; break; case D3D10_SRV_DIMENSION_TEXTURE2D: MipSlice = Desc.Texture2D.MostDetailedMip; break; case D3D10_SRV_DIMENSION_TEXTURE2DARRAY: MipSlice = Desc.Texture2DArray.MostDetailedMip; FirstArraySlice = Desc.Texture2DArray.FirstArraySlice; ArraySize = Desc.Texture2DArray.ArraySize; break; case D3D10_SRV_DIMENSION_TEXTURE2DMS: break; case D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY: FirstArraySlice = Desc.Texture2DMSArray.FirstArraySlice; ArraySize = Desc.Texture2DMSArray.ArraySize; break; case D3D10_SRV_DIMENSION_TEXTURE3D: MipSlice = Desc.Texture3D.MostDetailedMip; break; case D3D10_SRV_DIMENSION_TEXTURECUBE: MipSlice = Desc.TextureCube.MostDetailedMip; ArraySize = 6; break; case D3D10_SRV_DIMENSION_UNKNOWN: default: assert(0); return; } for (UINT ArraySlice = FirstArraySlice; ArraySlice < FirstArraySlice + ArraySize; ++ArraySlice) { image::Image *image; image = getSubResourceImage(pDevice, pResource, Desc.Format, ArraySlice, MipSlice); if (image) { char label[64]; _snprintf(label, sizeof label, "%s_RESOURCE_%u_ARRAY_%u_LEVEL_%u", shader, stage, ArraySlice, MipSlice); json.beginMember(label); json.writeImage(image); json.endMember(); // *_RESOURCE_* delete image; } } }
static inline void dumpTextureImage(JSONWriter &json, GLenum target, GLint level) { GLint width, height = 1, depth = 1; width = 0; glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); if (target != GL_TEXTURE_1D) { height = 0; glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); if (target == GL_TEXTURE_3D) { depth = 0; glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth); } } if (width <= 0 || height <= 0 || depth <= 0) { return; } else { char label[512]; GLint active_texture = GL_TEXTURE0; glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); snprintf(label, sizeof label, "%s, %s, level = %i", enumToString(active_texture), enumToString(target), level); json.beginMember(label); json.beginObject(); // Tell the GUI this is no ordinary object, but an image json.writeStringMember("__class__", "image"); json.writeNumberMember("__width__", width); json.writeNumberMember("__height__", height); json.writeNumberMember("__depth__", depth); // Hardcoded for now, but we could chose types more adequate to the // texture internal format json.writeStringMember("__type__", "uint8"); json.writeBoolMember("__normalized__", true); json.writeNumberMember("__channels__", 4); GLubyte *pixels = new GLubyte[depth*width*height*4]; resetPixelPackState(); glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels); restorePixelPackState(); json.beginMember("__data__"); char *pngBuffer; int pngBufferSize; Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize); json.writeBase64(pngBuffer, pngBufferSize); free(pngBuffer); json.endMember(); // __data__ delete [] pixels; json.endObject(); } }