SDL2 Invalid Renderer - sdl-2

I believe I have an SDL2 bug here and I wanted some verification. When I create a renderer it is invalid and I cannot initialize SDL_ttf because of this. Here is a quick demo program that exhibits the issue on my xubuntu 14.04 distribution. My graphics card is an NVIDIA GTX 550 Ti. Driver version 331.113 proprietary, tested.
#include <SDL2/SDL.h>
#include <string>
#include <stdexcept>
#include <iostream>
using namespace std;
int main() {
SDL_Window* _window;
SDL_Renderer* _renderer;
if( SDL_Init( SDL_INIT_EVERYTHING ) != 0 ) {
string error( SDL_GetError() );
throw runtime_error( "SDL could not initialize! SDL Error: " + error );
}
_window = SDL_CreateWindow( "Conscious", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 500, 500, SDL_WINDOW_SHOWN );
if( _window == NULL ) {
string error( SDL_GetError() );
throw runtime_error( "Window could not be created! SDL Error: " + error );
}
_renderer = SDL_CreateRenderer( _window , -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
if( _renderer == NULL ) {
string error( SDL_GetError() );
throw runtime_error( "Renderer could not be created! SDL Error: " + error );
}
cout << SDL_GetError() << endl;
return 0;
}
Let me know what you think!
Thanks,
Jonathon
--EDIT--
If you take out SDL_image and SDL_ttf the renderer is still returned as invalid.
Also this does not happen on windows with the same exact hardware. If this is not a bug would somebody please explain what could be wrong with such a simple example?
--EDIT EDIT--
This code prints out "Invalid renderer" on my system. If you have SDL2 please run it and let me know if you do too.

While it is indeed produces 'Invalid renderer' message, it isn't a problem because as SDL_GetError documentation states You must check the return values of SDL function calls to determine when to appropriately call SDL_GetError()., and SDL gave you no reason to look for error description in GetError.
Why it happens, by the way:
Breakpoint 1, 0x00007ffff7b00e90 in SDL_SetError_REAL () from /usr/lib64/libSDL2-2.0.so.0
(gdb) backtrace
#0 0x00007ffff7b00e90 in SDL_SetError_REAL () from /usr/lib64/libSDL2-2.0.so.0
#1 0x00007ffff7b8f124 in SDL_GL_GetProcAddress_REAL () from /usr/lib64/libSDL2-2.0.so.0
#2 0x00007ffff7b8f80b in SDL_GL_GetAttribute_REAL () from /usr/lib64/libSDL2-2.0.so.0
#3 0x00007ffff7b41bcf in GL_CreateRenderer () from /usr/lib64/libSDL2-2.0.so.0
#4 0x00007ffff7b3b66c in SDL_CreateRenderer_REAL () from /usr/lib64/libSDL2-2.0.so.0
#5 0x0000000000401383 in main ()
GL_CreateRenderer calls SDL_GetAttribute to get context version and such, which tries to load GL functions, which requires active renderer, but it isn't there yet. While not most eye-pleasant solution, it works well and it isn't a bug. Probable reason why you don't have it on windows is e.g. because it uses different renderer (d3d?).

Related

Regarding CFLocaleCopyCurrent API incorrect return value

At my workplace, we are in a situation where following standalone code below,
#include <CoreFoundation/CoreFoundation.h>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <boost/cast.hpp>
// Reference release
struct reference_close
{
void operator()(const void *ref) const
{
CFRelease(static_cast<CFTypeRef>(ref));
}
}; // end of reference_close structure
typedef std::unique_ptr<const void, reference_close> reference_uptr;
std::string get_user_locale()
{
reference_uptr ref_ptr(CFLocaleCopyCurrent());
CFLocaleRef locale_ref(static_cast<CFLocaleRef>(ref_ptr.get()));
if (locale_ref == nullptr)
{
return std::string();
}
const size_t default_size(128);
std::vector<char> buff(default_size);
CFStringRef str_ref(CFLocaleGetIdentifier(locale_ref));
// CFStringRef str_ref((CFStringRef)CFLocaleGetValue(locale_ref,kCFLocaleLanguageCode));
if (str_ref != nullptr)
{
CFIndex len(CFStringGetLength(str_ref) + 1);
if (len > boost::numeric_cast<CFIndex>(default_size))
{
buff.resize(len);
}
buff[0] = 0;
if (!CFStringGetCString(str_ref, &buff[0], len, kCFStringEncodingISOLatin1))
{
return std::string();
}
}
return std::string(&buff[0]);
} // end of get_user_locale()
int main()
{
std::cout << "get_user_locale() : "<<get_user_locale() << std::endl;
return 0;
}
gives us a different output on OS X 10.12 and 10.13 beta.
This is what we do in a nutshell.
On 10.12 machine
1) Set the preference language as ru and region as RU
2) Restart the machine
3) Get the output of "defaults read -g AppleLocale" to make sure that output is
{
ru_RU
}
4) Compile the code, run the exe. We get the output as { ru_RU }.
We then repeat the steps 1) to 3) on OS X 10.13 (beta) machine and then run the same exe (created on 10.12, you might ask why, its because of some our internal build system restrictions ) on 10.13 machine and the output we get is "en_RU" which is not correct.
Are we missing something here ? Or is this a known problem in OS X 10.13 (beta) ? If so, how do we fix this ?
UPDATE
We also wrote a following Objective-C code to use NSLocale interface and that too gave us same results i.e ru_RU on 10.12 and en_RU on 10.13 (beta)
#import <Foundation/Foundation.h>
int main()
{
#autoreleasepool
{
NSLog(#"localeIdentifier: %#", [[NSLocale currentLocale] localeIdentifier]);
}
}
The reason we were getting an incorrect value is because our app was not localized into the locale we expected e.g ru.
We corrected this by adding an empty ru.lproj directory into our app's Contents/Resources directory and the API started giving us the correct answer.

SDL2 on Raspberry Pi can't create renderer: "OpenGL context already created"

I set up SDL2 on the raspberry pi using the resources from this tutorial: https://www.youtube.com/watch?v=Yo7hO7GZ-ug I got it to compile and run. But when it reaches the point where it needs to setup the renderer, I get a NULL return value.
The accepted answer on this question suggests that the error "OpenGL context already created" is deceiving and that the OpenGL context hasn't been created at all. This would mean that my OpenGL is broken. The Raspberry Pi uses OpenGL ES and from what I understand, SDL is smart enough to use GLES instead of GL? I'm wondering if anyone else has had this kind of issue and if there's a known way to fix it.
This is my code:
#include <SDL2/SDL.h>
const char* WINDOW_TITLE = "steel";
int main(int argc, char** argv) {
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
// Setup window
window = SDL_CreateWindow(
WINDOW_TITLE, //Title
SDL_WINDOWPOS_CENTERED, // x pos
SDL_WINDOWPOS_CENTERED, // y pos
0, //width
0, //height
SDL_WINDOW_FULLSCREEN_DESKTOP);
if (window == NULL) {
printf("Could not create window %s\n", SDL_GetError());
return 1;
}
// Setup renderer
renderer = SDL_CreateRenderer(window, 0, 0);
if (renderer == NULL) {
printf("Could not create renderer %s\n", SDL_GetError());
return 1;
}
}
According to SDL_CreateRenderer documentation, you should specify -1 to its second parameter to ask for the first rendering driver supporting your requested flags. The one at index 0 might not be the correct one.

Use of TerminateExecution in V8

I'm experimenting with V8 at the moment. I want to be able to run some (possibly long-running) javascript in one thread and then be able to terminate the execution "gracefully" at will from another thread.
I've written this simple snippet to test the concept of Lockers and the usage of TerminateExecution:
void breaker( Isolate* isolate, int tid ) {
getchar(); //wait for keyboard input on stdin
std::cout << "Breaking V8 execution" << std::endl;
v8::Locker locker( isolate ); //lock the isolate
v8::V8::TerminateExecution( tid ); //and terminate it
}
int main( int argc, char **argv ) {
if( argc != 2 ) {
std::cout << "No script name given" << std::endl;
return 1;
}
Isolate* isolate = Isolate::New(); //create a new isolate
Isolate::Scope isolateScope( isolate ); //enter it
v8::Locker locker( isolate ); //lock the isolate
v8::Locker::StartPreemption( 100 ); //and start preemption
v8::HandleScope handle_scope( isolate ); //open a new handle scope
/*** inject a console object into the global context ***/
v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
Handle<Context> context = Context::New( NULL, globalTemplate );
v8::Context::Scope context_scope( context );
Console* console = new Console;
Handle<Object> jsConsole = wrap_console( isolate, console );
expose_property( jsConsole, String::New( "log" ), InvocationCallback( Console::consoleLog ) );
context->Global()->Set( String::New( "console" ), jsConsole, v8::ReadOnly );
/*******************************************************/
//read a javascript file supplied via console
std::string contents = read_file( argv[1] );
v8::Handle<v8::String> js = v8::String::New( contents.c_str() );
v8::TryCatch try_catch;
v8::Handle<v8::Script> script = v8::Script::Compile( js );
if( script.IsEmpty() ) {
report_exception( try_catch );
}
//start the breaker thread
std::thread th( breaker, isolate, v8::V8::GetCurrentThreadId() );
log_info( "running script" );
script->Run();
log_info( "Script execution finished" );
th.join();
}
However, I always get a segfault on the terminateExecution() call. What am I doing wrong here?
thanks for any help
The v8::V8::GetCurrentThreadId() and v8::V8::TerminateExecution(int) methods have been removed from the V8 API. I recommend that you don't use them. The preemption feature is probably also not long for this world.
Instead, simply call v8::V8::TerminateExecution(v8::Isolate*). And don't lock the isolate in your breaker thread, as doing so will block until your runner thread releases the isolate, which it won't do until script execution is finished.

How do you programmatically access the ambient light sensor on Mac OS X 10.5+?

I'm trying to programmatically access the ambient light sensor in a Mac application running on OS X 10.5 and above, but can't find a way to do this.
Two other questions had been posed about this here, "Accessing mac's sensor data" and "Disable ambient-light sensor screen dimming programmatically on OS X", but they either didn't address this or present solutions that break on 10.5 and up.
What private API does Apple use to access the ambient light-sensor data on OS X and/or how would I find it?
I've found the closest thing I can -- example code from a Firefox bug report last modified in April 2013. The following works, producing a simple CLI program to query the sensor (taken freely from https://bugzilla.mozilla.org/show_bug.cgi?id=793728#attach_664102). The service polled is "AppleLMUController", which you can then extract relevant information from -- the snippet below creates a serviceObject=IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleLMUController")), which is then used.
// lmutracker.mm
//
// clang -o lmutracker lmutracker.mm -framework IOKit -framework CoreFoundation
#include <mach/mach.h>
#import <IOKit/IOKitLib.h>
#import <CoreFoundation/CoreFoundation.h>
static double updateInterval = 0.1;
static io_connect_t dataPort = 0;
void updateTimerCallBack(CFRunLoopTimerRef timer, void *info) {
kern_return_t kr;
uint32_t outputs = 2;
uint64_t values[outputs];
kr = IOConnectCallMethod(dataPort, 0, nil, 0, nil, 0, values, &outputs, nil, 0);
if (kr == KERN_SUCCESS) {
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%8lld %8lld", values[0], values[1]);
return;
}
if (kr == kIOReturnBusy) {
return;
}
mach_error("I/O Kit error:", kr);
exit(kr);
}
int main(void) {
kern_return_t kr;
io_service_t serviceObject;
CFRunLoopTimerRef updateTimer;
serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleLMUController"));
if (!serviceObject) {
fprintf(stderr, "failed to find ambient light sensors\n");
exit(1);
}
kr = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort);
IOObjectRelease(serviceObject);
if (kr != KERN_SUCCESS) {
mach_error("IOServiceOpen:", kr);
exit(kr);
}
setbuf(stdout, NULL);
printf("%8ld %8ld", 0L, 0L);
updateTimer = CFRunLoopTimerCreate(kCFAllocatorDefault,
CFAbsoluteTimeGetCurrent() + updateInterval, updateInterval,
0, 0, updateTimerCallBack, NULL);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), updateTimer, kCFRunLoopDefaultMode);
CFRunLoopRun();
exit(0);
}
While #Landak's answer is good for the time, that ambient light sensor api seems to have been deprecated.
The code that works now is as follows:
// lmutracker.mm
//
// clang -o lmutracker lmutracker.mm -F /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/PrivateFrameworks -framework Foundation -framework IOKit -framework CoreFoundation -framework BezelServices
#include <mach/mach.h>
#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/hidsystem/IOHIDServiceClient.h>
typedef struct __IOHIDEvent *IOHIDEventRef;
#define kAmbientLightSensorEvent 12
#define IOHIDEventFieldBase(type) (type << 16)
extern "C" {
IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t, int32_t, int64_t);
double IOHIDEventGetFloatValue(IOHIDEventRef, int32_t);
IOHIDServiceClientRef ALCALSCopyALSServiceClient(void);
}
static double updateInterval = 0.1;
static IOHIDServiceClientRef client;
static IOHIDEventRef event;
void updateTimerCallBack(CFRunLoopTimerRef timer, void *info) {
double value;
event = IOHIDServiceClientCopyEvent(client, kAmbientLightSensorEvent, 0, 0);
value = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kAmbientLightSensorEvent));
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%8f", value);
CFRelease(event);
}
int main(void) {
kern_return_t kr;
CFRunLoopTimerRef updateTimer;
client = ALCALSCopyALSServiceClient();
if (client) {
event = IOHIDServiceClientCopyEvent(client, kAmbientLightSensorEvent, 0, 0);
}
if (!event) {
fprintf(stderr, "failed to find ambient light sensors\n");
exit(1);
}
CFRelease(event);
setbuf(stdout, NULL);
printf("%8f", 0.0);
updateTimer = CFRunLoopTimerCreate(kCFAllocatorDefault,
CFAbsoluteTimeGetCurrent() + updateInterval, updateInterval,
0, 0, updateTimerCallBack, NULL);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), updateTimer, kCFRunLoopDefaultMode);
CFRunLoopRun();
exit(0);
}
I found this in DarkModeBuddy (BSD 2-clause license), and adapted it into a cli tool in my dotfiles.
You can get the value of ambient light sensor using terminal.
For get the value first you should install the system management controller smc .exec then run it using terminal. After that run this command ./smc -l it's show's the list of all sensor's which exist on mac after that try to find the key which is ALSL this key give's the actual value of light ambient sensor of every mac.

Use of undeclared identifier 'kAudioUnitSubType_SpeechSynthesis...

I've been following the examples on Audio Units from Learning Core Audio book by Adamson and Avila. I'm getting the above error for some reason. I #include <CoreAudio/CoreAudio.h> even just to make sure I am importing the possible libraries for Audio, and made sure to configure the "Link Binary with Libraries" under the "Build Phases" part of target. I even changed the Base SDK to OSX 10.7 (as opposed to the default 10.8) to see what happens, but no cigar. And according to the documentation, the Speech Synthesis API is not fully deprecated in anyway -- some functions are, however. My MacBook is running 10.7.5. XCode is Version 4.6 (4H127.
Below I put a comment on where I got the error in CAPS. Any ideas?
//
// main.c
// CAsamplerSynthesisGraph
//
// Created by Edderic Ugaddan on 6/25/13.
// Copyright (c) 2013 Edderic Ugaddan. All rights reserved.
//
//#include <CoreFoundation/CoreFoundation.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#include <CoreAudio/CoreAudio.h>
// #define PART_II
#pragma mark user-data struct
// Insert Listing 7.19 here
typedef struct MyAUGraphPlayer {
AUGraph graph;
AudioUnit samplerAU;
} MyAUGraphPlayer;
#pragma mark utility functions
// Insert Listing 4.2 here
static void CheckError(OSStatus error, const char *operation) {
if (error == noErr) return;
char errorString[20];
// See if it appears to be a 4-char-code.
*(UInt32 *)*(errorString + 1) = CFSwapInt32HostToBig(error);
if (isprint(errorString[1]) && isprint(errorString[2]) &&
isprint(errorString[3]) && isprint(errorString[4])) {
errorString[0] = errorString[5] = '\'';
errorString[6] = '\0';
}
else {
// No, format it as an integer.
sprintf(errorString, "%d", (int) error);
fprintf(stderr, "Error: %s (%s)\n", operation, errorString);
exit(1);
}
}
void CreateMyAUGraph(MyAUGraphPlayer *player) {
// Insert Listing 7.21 here
// Create a new graph
CheckError(NewAUGraph(&player->graph),
"NewAUGraph failed");
// Generates a description that matches our output device (speakers)
AudioComponentDescription outputcd = {0};
outputcd.componentType = kAudioUnitType_Output;
outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
// Adds a node with above description to the graph
AUNode outputNode;
CheckError(AUGraphAddNode(player->graph,
&outputcd,
&outputNode),
"AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");
// Generates a description that will match a generator AU
// of type: sampler synthesizer
AudioComponentDescription samplercd = {0};
samplercd.componentType = kAudioUnitType_Generator;
samplercd.componentSubType = kAudioUnitSubType_SpeechSynthesis; // I GET ERROR HERE
samplercd.componentManufacturer = kAudioUnitManufacturer_Apple;
// Adds a node with above description to the graph
AUNode samplerNode;
CheckError(AUGraphAddNode(player->graph,
&samplercd,
&samplerNode),
"AUGraphAddNode[kAudioUnitSubType_samplerSynthesis] failed");
// Opening the graph opens all contained audio units, but
// does not allocate any resources yet
CheckError(AUGraphOpen(player->graph),
"AUGraphOpen failed");
// Gets the reference to the AudioUnit object for the
// sampler graph node
CheckError(AUGraphNodeInfo(player->graph,
samplerNode,
NULL,
&player->samplerAU),
"AUGraphNodeInfo failed");
#ifdef PART_II
// Insert Listing 7.24 - 7.26 here
#else
// Insert Listing 7.22 here
// Connect the output source of the sampler synthesis AU
// to the input source of the output node
CheckError(AUGraphConnectNodeInput(player->graph,
samplerNode,
0,
outputNode,
0),
"AUGraphConnectNodeInput failed");
#endif
}
// Replace with listing 7.23
void PrepareSamplerAU(MyAUGraphPlayer *player) {
// Sampler
}
#pragma mark main function
// Replace with listing 7.20
int main(int argc, const char * argv[])
{
MyAUGraphPlayer player = {0};
// Build a basic sampler->speakers graph
CreateMyAUGraph(&player);
// Configure the sampler synthesizer
PrepareSamplerAU(&player);
// Start playing
CheckError(AUGraphStart(player.graph),
"AUGraphStart failed");
// Sleep a while so the sampler can play out
usleep ((int)(10 * 1000. * 1000.));
// Cleanup
AUGraphStop(player.graph);
AUGraphUninitialize(player.graph);
AUGraphClose(player.graph);
return 0;
}
kAudioUnitSubType_SpeechSynthesis is declared in SpeechSynthesis.framework, which lives within the ApplicationServices.framework umbrella framework, so you should #import < ApplicationServices.framework>.

Resources