예제 #1
0
void Device_Stepper::UpdateInitialPinState(uint8_t device_number)
{
    if (ValidateConfig(device_number) == APP_ERROR_TYPE_SUCCESS &&
            !AxisInfo::GetStepperEnableState(device_number))
    {
        uint8_t current_state;
        uint8_t expected_state;
        uint8_t pin;

        expected_state = GetEnableInvert(device_number) ? INITIAL_PIN_STATE_HIGH : INITIAL_PIN_STATE_LOW;
        pin = GetEnablePin(device_number);
        if (!retrieve_initial_pin_state(pin, &current_state) && current_state != expected_state)
        {
            set_initial_pin_state(pin, expected_state);
        }

        expected_state = GetDirectionInvert(device_number) ? INITIAL_PIN_STATE_HIGH : INITIAL_PIN_STATE_LOW;
        pin = GetDirectionPin(device_number);
        if (!retrieve_initial_pin_state(pin, &current_state) && current_state != expected_state)
        {
            set_initial_pin_state(pin, expected_state);
        }

        expected_state = GetStepInvert(device_number) ? INITIAL_PIN_STATE_HIGH : INITIAL_PIN_STATE_LOW;
        pin = GetStepPin(device_number);
        if (!retrieve_initial_pin_state(pin, &current_state) && current_state != expected_state)
        {
            set_initial_pin_state(pin, expected_state);
        }
    }
}
예제 #2
0
EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy,
                                           EGLConfig config,
                                           EGLNativePixmapType pixmap,
                                           const EGLint *attrib_list)
{
    EVENT(
        "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = "
        "0x%0.8p, "
        "const EGLint *attrib_list = 0x%0.8p)",
        dpy, config, pixmap, attrib_list);
    Thread *thread = GetCurrentThread();

    Display *display      = static_cast<Display *>(dpy);
    Config *configuration = static_cast<Config *>(config);

    Error error = ValidateConfig(display, configuration);
    if (error.isError())
    {
        thread->setError(error);
        return EGL_NO_SURFACE;
    }

    UNIMPLEMENTED();  // FIXME

    thread->setError(NoError());
    return EGL_NO_SURFACE;
}
예제 #3
0
void RestoreConfig()
{
	int n;
	char *envname;
	char envbuf[256];
	char *name;
	char *ptr;
	char buf[80];

	SetColor(LIGHTWHITE);
	SetBackColor(BLUE);
	OpenWindow(10,10,3,60);
	SetColor(YELLOW);
	Print_At(10,13," Restore Predefined Configuration ");
	SetColor(LIGHTWHITE);
	Print_At(11,12,"Enter file name:");

	name=InputString(11,30,37,cfgfilename);
	if(name!=NULL && name[0]!=0)
	{
		strcpy(buf,name);
		ptr=(char *)strchr(buf,'.');
		if(ptr!=NULL) strset(ptr,0);
		strcpy(cfgfilename,buf);
		strcat(buf,".d32");
		n=open(buf,O_RDONLY | O_BINARY);
		if(n==-1)
		{
			envname=getenv("DOS32A");
			if(envname!=NULL)
			{
				ptr=strchr(envname,' ');
				if(ptr==NULL) ptr=strchr(envname,0);
				memset(envbuf,0,256);
				strncpy(envbuf,envname,(dword)ptr-(dword)envname);
				strcat(envbuf,"\\D32\\"); strcat(envbuf,buf);
				n=open(envbuf,O_RDWR | O_BINARY);
			}
		}
		if(n!=-1)
		{
			read(n,&id32,24);
			close(n);
			SetColor(LIGHTWHITE);
			SetBackColor(BLUE);
			strupr(buf);
			for(n=0; n<13; n++)
			{
				SetPos(24,66+n);
				PrintC(' ');
			}
			Print_At(24,66,"%.13s",buf);
		}
		else DiskError();
	}
	ValidateConfig();
	CloseWindow();
	if(mainmenu_sel==1) ShowBannerStatus();

}
예제 #4
0
std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(DXTexture* color_attachment,
                                                     DXTexture* depth_attachment)
{
  if (!ValidateConfig(color_attachment, depth_attachment))
    return nullptr;

  const AbstractTextureFormat color_format =
      color_attachment ? color_attachment->GetFormat() : AbstractTextureFormat::Undefined;
  const AbstractTextureFormat depth_format =
      depth_attachment ? depth_attachment->GetFormat() : AbstractTextureFormat::Undefined;
  const DXTexture* either_attachment = color_attachment ? color_attachment : depth_attachment;
  const u32 width = either_attachment->GetWidth();
  const u32 height = either_attachment->GetHeight();
  const u32 layers = either_attachment->GetLayers();
  const u32 samples = either_attachment->GetSamples();

  ID3D11RenderTargetView* rtv = nullptr;
  ID3D11RenderTargetView* integer_rtv = nullptr;
  if (color_attachment)
  {
    CD3D11_RENDER_TARGET_VIEW_DESC desc(
        color_attachment->IsMultisampled() ? D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY :
                                             D3D11_RTV_DIMENSION_TEXTURE2DARRAY,
        GetRTVFormatForHostFormat(color_attachment->GetFormat(), false), 0, 0,
        color_attachment->GetLayers());
    HRESULT hr =
        D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc, &rtv);
    CHECK(SUCCEEDED(hr), "Create render target view for framebuffer");

    // Only create the integer RTV on Win8+.
    DXGI_FORMAT integer_format = GetRTVFormatForHostFormat(color_attachment->GetFormat(), true);
    if (D3D::device1 && integer_format != desc.Format)
    {
      desc.Format = integer_format;
      hr = D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc,
                                               &integer_rtv);
      CHECK(SUCCEEDED(hr), "Create integer render target view for framebuffer");
    }
  }

  ID3D11DepthStencilView* dsv = nullptr;
  if (depth_attachment)
  {
    const CD3D11_DEPTH_STENCIL_VIEW_DESC desc(
        depth_attachment->GetConfig().IsMultisampled() ? D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY :
                                                         D3D11_DSV_DIMENSION_TEXTURE2DARRAY,
        GetDSVFormatForHostFormat(depth_attachment->GetFormat()), 0, 0,
        depth_attachment->GetLayers(), 0);
    HRESULT hr =
        D3D::device->CreateDepthStencilView(depth_attachment->GetD3DTexture(), &desc, &dsv);
    CHECK(SUCCEEDED(hr), "Create depth stencil view for framebuffer");
  }

  return std::make_unique<DXFramebuffer>(color_attachment, depth_attachment, color_format,
                                         depth_format, width, height, layers, samples, rtv,
                                         integer_rtv, dsv);
}
예제 #5
0
파일: varfilter.cpp 프로젝트: arsaccol/SLED
	int32_t VarFilterName::requiredMemoryHelper(const VarFilterNameConfig& varFilterNameConfig, ISequentialAllocator *pAllocator, void **ppThis)
	{
		SCE_SLED_ASSERT(pAllocator != NULL);
		SCE_SLED_ASSERT(ppThis != NULL);

		const int32_t iConfigError = ValidateConfig(varFilterNameConfig);
		if (iConfigError != 0)
			return iConfigError;

		VarFilterNameSeats seats;
		seats.Allocate(varFilterNameConfig, pAllocator);

		*ppThis = seats.m_this;
		return SCE_SLED_ERROR_OK;
	}
예제 #6
0
파일: varfilter.cpp 프로젝트: arsaccol/SLED
	int32_t VarFilterName::requiredMemory(const VarFilterNameConfig& varFilterNameConfig, std::size_t *iRequiredMemory)
	{
		SCE_SLED_ASSERT(iRequiredMemory != NULL);

		const int32_t iConfigError = ValidateConfig(varFilterNameConfig);
		if (iConfigError != 0)
			return iConfigError;

		SequentialAllocatorCalculator allocator;

		VarFilterNameSeats seats;
		seats.Allocate(varFilterNameConfig, &allocator);

		*iRequiredMemory = allocator.bytesAllocated();
		return SCE_SLED_ERROR_OK;
	}
예제 #7
0
	int32_t StringArray::requiredMemoryHelper(const StringArrayConfig *pConfig, ISequentialAllocator *pAllocator, void **ppThis)
	{
		SCE_SLED_ASSERT(pConfig != NULL);
		SCE_SLED_ASSERT(pAllocator != NULL);
		SCE_SLED_ASSERT(ppThis != NULL);

		const int32_t iConfigError = ValidateConfig(*pConfig);
		if (iConfigError != 0)
			return iConfigError;

		StringArraySeats seats;
		seats.Allocate(pConfig, pAllocator);

		*ppThis = seats.m_this;
		return SCE_SLED_ERROR_OK;
	}
예제 #8
0
	int32_t LuaPlugin::requiredMemory(const LuaPluginConfig& luaConfig, std::size_t *iRequiredMemory)
	{
		SCE_SLED_ASSERT(iRequiredMemory != NULL);

		const int32_t iConfigError = ValidateConfig(luaConfig);
		if (iConfigError != 0)
			return iConfigError;

		SequentialAllocatorCalculator allocator;
		{
			LuaPluginSeats seats;
			seats.Allocate(luaConfig, &allocator);
		}

		*iRequiredMemory = allocator.bytesAllocated();	
		return SCE_SLED_ERROR_OK;
	}
예제 #9
0
	int32_t StringArray::requiredMemory(const StringArrayConfig *pConfig, std::size_t *iRequiredMemory)
	{
		SCE_SLED_ASSERT(pConfig != NULL);
		SCE_SLED_ASSERT(iRequiredMemory != NULL);

		const int32_t iConfigError = ValidateConfig(*pConfig);
		if (iConfigError != 0)
			return iConfigError;

		SequentialAllocatorCalculator allocator;

		StringArraySeats seats;	
		seats.Allocate(pConfig, &allocator);

		*iRequiredMemory = allocator.bytesAllocated();
		return SCE_SLED_ERROR_OK;
	}
예제 #10
0
void main(int argc, char *argv[])
{
	int n;

	memset(startdir,0,sizeof(startdir));
	memset(cfgfilename,0,sizeof(cfgfilename));
	ArgInit(argc, argv);
	VideoInit();
	ShowCopyright(argc, argv);
//	CheckIfLocked();
	ShowSysInfo();
	ShowEnvInfo();
	ShowMainMenu();
	ShowMemory();
//	CheckVersion();
	ValidateConfig();

l1:	ShowMemory();
	SelectMainMenu();
l2:	switch(mainmenu_sel)
	{
		case 0:		ShowKernelMenu();
					if(keycode==F2)
					{
						ShowMemory();
						mainmenu_sel=1;
						goto l2;
					} else break;
		case 1:		ShowExtenderMenu();
					if(keycode==F1)
					{
						ShowMemory();
						mainmenu_sel=0;
						goto l2;
					} else break;
		case 2:		CreateConfig(); break;
		case 3:		RestoreConfig();break;
		case 4:		id32=id32_old; ClearConfigName(); break;
		case 5:		DiscardExit(); break;
		case 6:		ApplyExit(); break;
	}
	goto l1;
}
예제 #11
0
std::unique_ptr<NullFramebuffer> NullFramebuffer::Create(const NullTexture* color_attachment,
                                                         const NullTexture* depth_attachment)
{
  if (!ValidateConfig(color_attachment, depth_attachment))
    return nullptr;

  const AbstractTextureFormat color_format =
      color_attachment ? color_attachment->GetFormat() : AbstractTextureFormat::Undefined;
  const AbstractTextureFormat depth_format =
      depth_attachment ? depth_attachment->GetFormat() : AbstractTextureFormat::Undefined;
  const NullTexture* either_attachment = color_attachment ? color_attachment : depth_attachment;
  const u32 width = either_attachment->GetWidth();
  const u32 height = either_attachment->GetHeight();
  const u32 layers = either_attachment->GetLayers();
  const u32 samples = either_attachment->GetSamples();

  return std::make_unique<NullFramebuffer>(color_format, depth_format, width, height, layers,
                                           samples);
}
EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
    EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
          "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);

    Display *display = static_cast<Display*>(dpy);
    Config *configuration = static_cast<Config*>(config);

    Error error = ValidateConfig(display, configuration);
    if (error.isError())
    {
        SetGlobalError(error);
        return EGL_NO_SURFACE;
    }

    UNIMPLEMENTED();   // FIXME

    SetGlobalError(Error(EGL_SUCCESS));
    return EGL_NO_SURFACE;
}
EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
    EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
          dpy, config, attribute, value);

    Display *display = static_cast<Display*>(dpy);
    Config *configuration = static_cast<Config*>(config);

    Error error = ValidateConfig(display, configuration);
    if (error.isError())
    {
        SetGlobalError(error);
        return EGL_FALSE;
    }

    if (!display->getConfigAttrib(configuration, attribute, value))
    {
        SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
        return EGL_FALSE;
    }

    SetGlobalError(Error(EGL_SUCCESS));
    return EGL_TRUE;
}
예제 #14
0
void LoadConfig()
{
	agbPrint = ReadPrefHex("agbPrint");
	autoFireMaxCount = fromDec(ReadPrefString("autoFireMaxCount"));
	autoFrameSkip = ReadPref("autoFrameSkip", 0);
	autoLoadMostRecent = ReadPref("autoLoadMostRecent", 0);
	autoPatch = ReadPref("autoPatch", 1);
	autoSaveLoadCheatList = ReadPref("autoSaveCheatList", 1);
	aviRecordDir = ReadPrefString("aviRecordDir");
	batteryDir = ReadPrefString("batteryDir");
	biosFileNameGB = ReadPrefString("biosFileGB");
	biosFileNameGBA = ReadPrefString("biosFileGBA");
	biosFileNameGBC = ReadPrefString("biosFileGBC");
	captureFormat = ReadPref("captureFormat", 0);
	cheatsEnabled = ReadPref("cheatsEnabled", 0);
	cpuDisableSfx = ReadPref("disableSfx", 0);
	cpuSaveType = ReadPrefHex("saveType");
	disableMMX = ReadPref("disableMMX", 0);
	disableStatusMessages = ReadPrefHex("disableStatus");
	filterMT = ReadPref("filterEnableMultiThreading", 0);
	filter = ReadPref("filter", 0);
	frameSkip = ReadPref("frameSkip", 0);
	fsAdapter = ReadPref("fsAdapter", 0);
	fsColorDepth = ReadPref("fsColorDepth", 32);
	fsFrequency = ReadPref("fsFrequency", 60);
	fsHeight = ReadPref("fsHeight", 600);
	fsWidth = ReadPref("fsWidth", 800);
	fullScreen = ReadPrefHex("fullScreen");
	fullScreenStretch = ReadPref("stretch", 0);
	gbBorderAutomatic = ReadPref("borderAutomatic", 0);
	gbBorderOn = ReadPrefHex("borderOn");
	gbColorOption = ReadPref("colorOption", 0);
	gbEmulatorType = ReadPref("emulatorType", 1);
	gbFrameSkip = ReadPref("gbFrameSkip", 0);
	gbPaletteOption = ReadPref("gbPaletteOption", 0);
	gbSoundSetDeclicking(ReadPref("gbSoundDeclicking", 1));
	gb_effects_config.echo = (float)ReadPref("gbSoundEffectsEcho", 20) / 100.0f;
	gb_effects_config.enabled = ReadPref("gbSoundEffectsEnabled", 0);
	gb_effects_config.stereo = (float)ReadPref("gbSoundEffectsStereo", 15) / 100.0f;
	gb_effects_config.surround = ReadPref("gbSoundEffectsSurround", 0);
	gdbBreakOnLoad = ReadPref("gdbBreakOnLoad", 0);
	gdbPort = ReadPref("gdbPort", 55555);
	glFilter = ReadPref("glFilter", 1);
	ifbType = ReadPref("ifbType", 0);
	joypadDefault = ReadPref("joypadDefault", 0);
	languageOption = ReadPref("language", 1);
	linkAuto = ReadPref("LinkAuto", 1);
	linkHacks = ReadPref("LinkHacks", 0);
	linkHostAddr = ReadPrefString("LinkHostAddr", "localhost");
	linkMode = ReadPref("LinkMode", 0); // LINK_DISCONNECTED = 0
	linkNumPlayers = ReadPref("LinkNumPlayers", 2);
	linkTimeout = ReadPref("LinkTimeout", 1);
	loadDotCodeFile = ReadPrefString("loadDotCodeFile");
	maxScale = ReadPref("maxScale", 0);
	movieRecordDir = ReadPrefString("movieRecordDir");
	openGL = ReadPrefHex("openGL");
	optFlashSize = ReadPrefHex("flashSize");
	pauseWhenInactive = ReadPref("pauseWhenInactive", 1);
	recentFreeze = ReadPref("recentFreeze", 0);
	rewindTimer = ReadPref("rewindTimer", 0);
	romDirGB = ReadPrefString("romDirGB");
	romDirGBA = ReadPrefString("romDirGBA");
	romDirGBC = ReadPrefString("romDirGBC");
	rtcEnabled = ReadPref("rtcEnabled", 0);
	saveDir = ReadPrefString("saveDir");
	saveDotCodeFile = ReadPrefString("saveDotCodeFile");
	screenShotDir = ReadPrefString("screenShotDir");
	showSpeed = ReadPref("showSpeed", 0);
	showSpeedTransparent = ReadPref("showSpeedTransparent", 1);
	skipBios = ReadPref("skipBios", 0);
	skipSaveGameBattery = ReadPref("skipSaveGameBattery", 0);
	skipSaveGameCheats = ReadPref("skipSaveGameCheats", 0);
	soundFiltering = (float)ReadPref("gbaSoundFiltering", 50) / 100.0f;
	soundInterpolation = ReadPref("gbaSoundInterpolation", 1);
	soundRecordDir = ReadPrefString("soundRecordDir");
	threadPriority = ReadPref("priority", 2);
	throttle = ReadPref("throttle", 100);
	tripleBuffering = ReadPref("tripleBuffering", 0);
	useBios = ReadPrefHex("useBiosGBA");
	useBiosFileGB = ReadPref("useBiosGB", 0);
	useBiosFileGBA = ReadPref("useBiosGBA", 0);
	useBiosFileGBC = ReadPref("useBiosGBC", 0);
	videoOption = ReadPref("video", 2); // VIDEO_3X = 2
	vsync = ReadPref("vsync", false);
	windowPositionX = ReadPref("windowX", 0);
	windowPositionY = ReadPref("windowY", 0);
	winFlashSize = ReadPref("flashSize", 0x10000);
	winGbBorderOn = ReadPref("borderOn", 0);
	winGbPrinterEnabled = ReadPref("gbPrinter", 0);

	int soundQuality = (ReadPrefHex("soundQuality"));
	switch (soundQuality) {
	case 1:
	case 2:
	case 4:
		break;
	default:
		log("Unknown sound quality %d. Defaulting to 22Khz\n", soundQuality);
		soundQuality = 2;
		break;
	}
	soundSetSampleRate(44100 / soundQuality);
	int volume = ReadPref("soundVolume", 100);
	float volume_percent = volume / 100.0f;
	if (volume_percent < 0.0 || volume_percent > SOUND_MAX_VOLUME)
		volume_percent = 1.0;
	soundSetVolume(volume_percent);

	soundSetEnable((ReadPrefHex("soundEnable", 0x30f)) & 0x30f);
	if ((ReadPrefHex("soundStereo"))) {
		gb_effects_config.enabled = true;
	}
	if ((ReadPrefHex("soundEcho"))) {
		gb_effects_config.enabled = true;
	}
	if ((ReadPrefHex("soundSurround"))) {
		gb_effects_config.surround = true;
		gb_effects_config.enabled = true;
	}

	if (optFlashSize == 0)
		flashSetSize(0x10000);
	else
		flashSetSize(0x20000);

	rtcEnable(rtcEnabled ? true : false);
	agbPrintEnable(agbPrint ? true : false);

	for (int i = 0; i < 24;) {
		systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
		systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
		systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
		systemGbPalette[i++] = 0;
	}

	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;

	optPrintUsage = 0;

	// TODO
	//int s = ReadPref("mapViewStretch", 0);
	//m_size = ReadPref("memViewerDataSize", 0);
	//m_stretch = ReadPref("GBOamViewStretch", 0);
	//m_stretch = ReadPref("tileViewStretch", 0);
	//numberType = ReadPref("cheatsNumberType", 2);
	//numberType = ReadPref("gbCheatsNumberType", 2);
	//restoreValues = ReadPref("cheatsRestore", 0) ?
	//scale = ReadPref("printerScale", 0);
	//searchType = ReadPref("cheatsSearchType", SEARCH_EQ);
	//searchType = ReadPref("gbCheatsSearchType",
	//selectedFilter = ReadPref(("selectedFilter"), 0);
	//sizeType = ReadPref("cheatsSizeType", 0);
	//sizeType = ReadPref("gbCheatsSizeType", 0);
	//updateValues = ReadPref("cheatsUpdate", 0);
	//updateValues = ReadPref("gbCheatsUpdate", 0);
	//valueType = ReadPref("cheatsValueType", 0);
	//valueType = ReadPref("gbCheatsValueType", 0);

	ValidateConfig();
}
예제 #15
0
Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer,
                                            Config *config, const AttributeMap& attributes)
{
    Error error = ValidateConfig(display, config);
    if (error.isError())
    {
        return error;
    }

    const DisplayExtensions &displayExtensions = display->getExtensions();

    switch (buftype)
    {
      case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
        if (!displayExtensions.d3dShareHandleClientBuffer)
        {
            return Error(EGL_BAD_PARAMETER);
        }
        if (buffer == nullptr)
        {
            return Error(EGL_BAD_PARAMETER);
        }
        break;

      default:
        return Error(EGL_BAD_PARAMETER);
    }

    for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
    {
        EGLint attribute = attributeIter->first;
        EGLint value = attributeIter->second;

        switch (attribute)
        {
          case EGL_WIDTH:
          case EGL_HEIGHT:
            if (!displayExtensions.d3dShareHandleClientBuffer)
            {
                return Error(EGL_BAD_PARAMETER);
            }
            if (value < 0)
            {
                return Error(EGL_BAD_PARAMETER);
            }
            break;

          case EGL_TEXTURE_FORMAT:
            switch (value)
            {
              case EGL_NO_TEXTURE:
              case EGL_TEXTURE_RGB:
              case EGL_TEXTURE_RGBA:
                break;
              default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          case EGL_TEXTURE_TARGET:
            switch (value)
            {
              case EGL_NO_TEXTURE:
              case EGL_TEXTURE_2D:
                break;
              default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          case EGL_MIPMAP_TEXTURE:
            break;

          default:
            return Error(EGL_BAD_ATTRIBUTE);
        }
    }

    if (!(config->surfaceType & EGL_PBUFFER_BIT))
    {
        return Error(EGL_BAD_MATCH);
    }

    EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
    EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
    if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
        (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
    {
        return Error(EGL_BAD_MATCH);
    }

    if ((textureFormat == EGL_TEXTURE_RGB  && config->bindToTextureRGB  != EGL_TRUE) ||
        (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
    {
        return Error(EGL_BAD_ATTRIBUTE);
    }

    if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
    {
        EGLint width = attributes.get(EGL_WIDTH, 0);
        EGLint height = attributes.get(EGL_HEIGHT, 0);

        if (width == 0 || height == 0)
        {
            return Error(EGL_BAD_ATTRIBUTE);
        }

        const Caps &caps = display->getCaps();
        if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
        {
            return Error(EGL_BAD_MATCH);
        }
    }

    return Error(EGL_SUCCESS);
}
예제 #16
0
Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWindowType window,
                                  const AttributeMap& attributes)
{
    Error error = ValidateConfig(display, config);
    if (error.isError())
    {
        return error;
    }

    if (!display->isValidNativeWindow(window))
    {
        return Error(EGL_BAD_NATIVE_WINDOW);
    }

    const DisplayExtensions &displayExtensions = display->getExtensions();

    for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
    {
        EGLint attribute = attributeIter->first;
        EGLint value = attributeIter->second;

        switch (attribute)
        {
          case EGL_RENDER_BUFFER:
            switch (value)
            {
              case EGL_BACK_BUFFER:
                break;
              case EGL_SINGLE_BUFFER:
                return Error(EGL_BAD_MATCH);   // Rendering directly to front buffer not supported
              default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
            if (!displayExtensions.postSubBuffer)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          case EGL_WIDTH:
          case EGL_HEIGHT:
            if (!displayExtensions.windowFixedSize)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            if (value < 0)
            {
                return Error(EGL_BAD_PARAMETER);
            }
            break;

          case EGL_FIXED_SIZE_ANGLE:
            if (!displayExtensions.windowFixedSize)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          case EGL_VG_COLORSPACE:
            return Error(EGL_BAD_MATCH);

          case EGL_VG_ALPHA_FORMAT:
            return Error(EGL_BAD_MATCH);

          default:
            return Error(EGL_BAD_ATTRIBUTE);
        }
    }

    if (Display::hasExistingWindowSurface(window))
    {
        return Error(EGL_BAD_ALLOC);
    }

    return Error(EGL_SUCCESS);
}
예제 #17
0
Error ValidateCreatePbufferSurface(Display *display, Config *config, const AttributeMap& attributes)
{
    Error error = ValidateConfig(display, config);
    if (error.isError())
    {
        return error;
    }

    for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
    {
        EGLint attribute = attributeIter->first;
        EGLint value = attributeIter->second;

        switch (attribute)
        {
          case EGL_WIDTH:
          case EGL_HEIGHT:
            if (value < 0)
            {
                return Error(EGL_BAD_PARAMETER);
            }
            break;

          case EGL_LARGEST_PBUFFER:
            break;

          case EGL_TEXTURE_FORMAT:
            switch (value)
            {
              case EGL_NO_TEXTURE:
              case EGL_TEXTURE_RGB:
              case EGL_TEXTURE_RGBA:
                break;
              default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          case EGL_TEXTURE_TARGET:
            switch (value)
            {
              case EGL_NO_TEXTURE:
              case EGL_TEXTURE_2D:
                break;
              default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          case EGL_MIPMAP_TEXTURE:
            break;

          case EGL_VG_COLORSPACE:
            break;

          case EGL_VG_ALPHA_FORMAT:
            break;

          default:
            return Error(EGL_BAD_ATTRIBUTE);
        }
    }

    if (!(config->surfaceType & EGL_PBUFFER_BIT))
    {
        return Error(EGL_BAD_MATCH);
    }

    const Caps &caps = display->getCaps();

    EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
    EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);

    if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
        (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
    {
        return Error(EGL_BAD_MATCH);
    }

    if ((textureFormat == EGL_TEXTURE_RGB  && config->bindToTextureRGB != EGL_TRUE) ||
        (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
    {
        return Error(EGL_BAD_ATTRIBUTE);
    }

    EGLint width = attributes.get(EGL_WIDTH, 0);
    EGLint height = attributes.get(EGL_HEIGHT, 0);
    if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
    {
        return Error(EGL_BAD_MATCH);
    }

    return Error(EGL_SUCCESS);
}
예제 #18
0
Error ValidateCreateContext(Display *display, Config *configuration, gl::Context *shareContext,
                            const AttributeMap& attributes)
{
    Error error = ValidateConfig(display, configuration);
    if (error.isError())
    {
        return error;
    }

    // Get the requested client version (default is 1) and check it is 2 or 3.
    EGLint clientMajorVersion = 1;
    EGLint clientMinorVersion = 0;
    EGLint contextFlags = 0;
    bool resetNotification = false;
    bool robustAccess = false;
    for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
    {
        EGLint attribute = attributeIter->first;
        EGLint value = attributeIter->second;

        switch (attribute)
        {
          case EGL_CONTEXT_CLIENT_VERSION:
            clientMajorVersion = value;
            break;

          case EGL_CONTEXT_MINOR_VERSION:
            clientMinorVersion = value;
            break;

          case EGL_CONTEXT_FLAGS_KHR:
            contextFlags = value;
            break;

          case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
            // Only valid for OpenGL (non-ES) contexts
            return Error(EGL_BAD_ATTRIBUTE);

          case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
            if (!display->getExtensions().createContextRobustness)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            if (value != EGL_TRUE && value != EGL_FALSE)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            robustAccess = (value == EGL_TRUE);
            break;

          case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
            static_assert(EGL_LOSE_CONTEXT_ON_RESET_EXT == EGL_LOSE_CONTEXT_ON_RESET_KHR, "EGL extension enums not equal.");
            static_assert(EGL_NO_RESET_NOTIFICATION_EXT == EGL_NO_RESET_NOTIFICATION_KHR, "EGL extension enums not equal.");
            // same as EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, fall through
          case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
            if (!display->getExtensions().createContextRobustness)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            if (value == EGL_LOSE_CONTEXT_ON_RESET_EXT)
            {
                resetNotification = true;
            }
            else if (value != EGL_NO_RESET_NOTIFICATION_EXT)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

          default:
            return Error(EGL_BAD_ATTRIBUTE);
        }
    }

    if ((clientMajorVersion != 2 && clientMajorVersion != 3) || clientMinorVersion != 0)
    {
        return Error(EGL_BAD_CONFIG);
    }

    if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR))
    {
        return Error(EGL_BAD_CONFIG);
    }

    // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES
    const EGLint validContextFlags = (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR |
                                      EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
    if ((contextFlags & ~validContextFlags) != 0)
    {
        return Error(EGL_BAD_ATTRIBUTE);
    }

    if ((contextFlags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) > 0)
    {
        robustAccess = true;
    }

    if (robustAccess)
    {
        // Unimplemented
        return Error(EGL_BAD_CONFIG);
    }

    if (shareContext)
    {
        // Shared context is invalid or is owned by another display
        if (!display->isValidContext(shareContext))
        {
            return Error(EGL_BAD_MATCH);
        }

        if (shareContext->isResetNotificationEnabled() != resetNotification)
        {
            return Error(EGL_BAD_MATCH);
        }

        if (shareContext->getClientVersion() != clientMajorVersion)
        {
            return Error(EGL_BAD_CONTEXT);
        }
    }

    return Error(EGL_SUCCESS);
}
예제 #19
0
Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWindowType window,
                                  const AttributeMap& attributes)
{
    ANGLE_TRY(ValidateConfig(display, config));

    if (!display->isValidNativeWindow(window))
    {
        return Error(EGL_BAD_NATIVE_WINDOW);
    }

    const DisplayExtensions &displayExtensions = display->getExtensions();

    for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
    {
        EGLAttrib attribute = attributeIter->first;
        EGLAttrib value     = attributeIter->second;

        switch (attribute)
        {
        case EGL_RENDER_BUFFER:
            switch (value)
            {
            case EGL_BACK_BUFFER:
                break;
            case EGL_SINGLE_BUFFER:
                return Error(EGL_BAD_MATCH);   // Rendering directly to front buffer not supported
            default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
            if (!displayExtensions.postSubBuffer)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
            if (!displayExtensions.flexibleSurfaceCompatibility)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        case EGL_WIDTH:
        case EGL_HEIGHT:
            if (!displayExtensions.windowFixedSize)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            if (value < 0)
            {
                return Error(EGL_BAD_PARAMETER);
            }
            break;

        case EGL_FIXED_SIZE_ANGLE:
            if (!displayExtensions.windowFixedSize)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        case EGL_SURFACE_ORIENTATION_ANGLE:
            if (!displayExtensions.surfaceOrientation)
            {
                return Error(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled.");
            }
            break;

        case EGL_VG_COLORSPACE:
            return Error(EGL_BAD_MATCH);

        case EGL_VG_ALPHA_FORMAT:
            return Error(EGL_BAD_MATCH);

        case EGL_DIRECT_COMPOSITION_ANGLE:
            if (!displayExtensions.directComposition)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        default:
            return Error(EGL_BAD_ATTRIBUTE);
        }
    }

    if (Display::hasExistingWindowSurface(window))
    {
        return Error(EGL_BAD_ALLOC);
    }

    return Error(EGL_SUCCESS);
}
예제 #20
0
Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer,
        Config *config, const AttributeMap& attributes)
{
    ANGLE_TRY(ValidateConfig(display, config));

    const DisplayExtensions &displayExtensions = display->getExtensions();

    switch (buftype)
    {
    case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
        if (!displayExtensions.d3dShareHandleClientBuffer)
        {
            return Error(EGL_BAD_PARAMETER);
        }
        if (buffer == nullptr)
        {
            return Error(EGL_BAD_PARAMETER);
        }
        break;

    default:
        return Error(EGL_BAD_PARAMETER);
    }

    for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
    {
        EGLAttrib attribute = attributeIter->first;
        EGLAttrib value     = attributeIter->second;

        switch (attribute)
        {
        case EGL_WIDTH:
        case EGL_HEIGHT:
            if (!displayExtensions.d3dShareHandleClientBuffer)
            {
                return Error(EGL_BAD_PARAMETER);
            }
            if (value < 0)
            {
                return Error(EGL_BAD_PARAMETER);
            }
            break;

        case EGL_TEXTURE_FORMAT:
            switch (value)
            {
            case EGL_NO_TEXTURE:
            case EGL_TEXTURE_RGB:
            case EGL_TEXTURE_RGBA:
                break;
            default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        case EGL_TEXTURE_TARGET:
            switch (value)
            {
            case EGL_NO_TEXTURE:
            case EGL_TEXTURE_2D:
                break;
            default:
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        case EGL_MIPMAP_TEXTURE:
            break;

        case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
            if (!displayExtensions.flexibleSurfaceCompatibility)
            {
                return Error(
                           EGL_BAD_ATTRIBUTE,
                           "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without "
                           "EGL_ANGLE_flexible_surface_compatibility support.");
            }
            break;

        default:
            return Error(EGL_BAD_ATTRIBUTE);
        }
    }

    if (!(config->surfaceType & EGL_PBUFFER_BIT))
    {
        return Error(EGL_BAD_MATCH);
    }

    EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
    EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
    if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
            (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
    {
        return Error(EGL_BAD_MATCH);
    }

    if ((textureFormat == EGL_TEXTURE_RGB  && config->bindToTextureRGB  != EGL_TRUE) ||
            (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
    {
        return Error(EGL_BAD_ATTRIBUTE);
    }

    if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
    {
        EGLint width  = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0));
        EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0));

        if (width == 0 || height == 0)
        {
            return Error(EGL_BAD_ATTRIBUTE);
        }

        const Caps &caps = display->getCaps();
        if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
        {
            return Error(EGL_BAD_MATCH);
        }
    }

    return Error(EGL_SUCCESS);
}
예제 #21
0
파일: config.c 프로젝트: axle-h/SNESDev-RPi
bool TryGetSNESDevConfig(const char *fileName, const int argc, char **argv, SNESDevConfig *const config) {
    const Arguments arguments = ParseArguments(argc, argv);

    cfg_opt_t GamepadOpts[] = {
            CFG_BOOL(CFG_ENABLED, cfg_false, CFGF_NONE),
            CFG_INT(CFG_GPIO, 0, CFGF_NONE),
            CFG_END()
    };

    cfg_opt_t GamepadsOpts[] = {
            CFG_SEC(CFG_GAMEPAD, GamepadOpts, CFGF_MULTI | CFGF_TITLE),
            CFG_INT_CB(CFG_GAMEPAD_TYPE, 0, CFGF_NONE, &VerifyGamepadType),
            CFG_INT(CFG_CLOCK_GPIO, 0, CFGF_NONE),
            CFG_INT(CFG_LATCH_GPIO, 0, CFGF_NONE),
            CFG_INT(CFG_POLL_FREQ, 0, CFGF_NONE),
            CFG_END()
    };

    cfg_opt_t ButtonOpts[] = {
            CFG_BOOL(CFG_ENABLED, cfg_false, CFGF_NONE),
            CFG_INT_CB(CFG_KEY, 0, CFGF_NONE, &VerifyInputKey),
            CFG_INT(CFG_GPIO, 0, CFGF_NONE),
            CFG_END()
    };

    cfg_opt_t ButtonsOpts[] = {
            CFG_SEC(CFG_BUTTON, ButtonOpts, CFGF_MULTI | CFGF_TITLE),
            CFG_INT(CFG_POLL_FREQ, 0, CFGF_NONE),
            CFG_END()
    };

    cfg_opt_t opts[] = {
            CFG_SEC(CFG_GAMEPADS, GamepadsOpts, CFGF_NONE),
            CFG_SEC(CFG_BUTTONS, ButtonsOpts, CFGF_NONE),
            CFG_END()
    };

    cfg_t *cfg;
    cfg = cfg_init(opts, CFGF_NOCASE);

    if (access(fileName, F_OK) == -1 || cfg_parse(cfg, fileName) != CFG_SUCCESS) {
        fprintf(stderr, "Cannot read config file %s\n", fileName);
        return false;
    }

    // Initialize from arguments.
    memset(config, 0, sizeof(SNESDevConfig));
    config->RunAsDaemon = !arguments.DebugEnabled && arguments.RunAsDaemon;
    config->DebugEnabled = arguments.DebugEnabled;
    config->Verbose = config->RunAsDaemon ? 0 : arguments.Verbose;

    // PidFile came from argv so will be way down teh stack :-)
    config->PidFile = arguments.PidFile;

    // Parse gamepad section
    GamepadsConfig *gamepadsConfig = &config->Gamepads;
    cfg_t *gamepadsSection = cfg_getsec(cfg, CFG_GAMEPADS);
    gamepadsConfig->ClockGpio = (uint8_t) SafeToUnsigned(cfg_getint(gamepadsSection, CFG_CLOCK_GPIO));
    gamepadsConfig->LatchGpio = (uint8_t) SafeToUnsigned(cfg_getint(gamepadsSection, CFG_LATCH_GPIO));

    unsigned int pollFrequency = SafeToUnsigned(cfg_getint(gamepadsSection, CFG_POLL_FREQ));
    if(pollFrequency > 0) {
        gamepadsConfig->PollFrequency = (unsigned int)(1000 / (double)pollFrequency);
    }
    gamepadsConfig->Type = (GamepadType)cfg_getint(gamepadsSection, CFG_GAMEPAD_TYPE);
    unsigned int numberOfGamepads = cfg_size(gamepadsSection, CFG_GAMEPAD);

    // Parse gamepads
    // TODO: Sort by gamepad id.
    for(unsigned int i = 0; i < numberOfGamepads; i++) {
        cfg_t *gamepadSection = cfg_getnsec(gamepadsSection, CFG_GAMEPAD, i);

        bool enabled = cfg_getbool(gamepadSection, CFG_ENABLED) ? true : false;
        if(!enabled) {
            continue;
        }

        GamepadConfig *gamepadConfig = gamepadsConfig->Gamepads + gamepadsConfig->Total;
        gamepadConfig->Id = (unsigned int) atoi(cfg_title(gamepadSection));
        gamepadConfig->DataGpio = (uint8_t) SafeToUnsigned(cfg_getint(gamepadSection, CFG_GPIO));
        gamepadsConfig->Total++;

        if(gamepadsConfig->Total > SNESDEV_MAX_GAMEPADS) {
            break;
        }
    }

    // Parse buttons section.
    ButtonsConfig *buttonsConfig = &config->Buttons;
    cfg_t *buttonsSection = cfg_getsec(cfg, CFG_BUTTONS);
    pollFrequency = SafeToUnsigned(cfg_getint(buttonsSection, CFG_POLL_FREQ));
    if(pollFrequency > 0) {
        buttonsConfig->PollFrequency = (unsigned int) (1000 / (double)pollFrequency);
    }
    unsigned int numberOfButtons = cfg_size(buttonsSection, CFG_BUTTON);

    // Parse buttons
    // TODO: Sort by button id.
    for (unsigned int i = 0; i < numberOfButtons; i++) {
        cfg_t *buttonSection = cfg_getnsec(buttonsSection, CFG_BUTTON, i);

        bool enabled = cfg_getbool(buttonSection, CFG_ENABLED) ? true : false;
        if(!enabled) {
            continue;
        }

        ButtonConfig *buttonConfig = buttonsConfig->Buttons + buttonsConfig->Total;
        buttonConfig->Id = (unsigned int) atoi(cfg_title(buttonSection));
        buttonConfig->Key = (InputKey) cfg_getint(buttonSection, CFG_KEY);
        buttonConfig->DataGpio = (uint8_t) SafeToUnsigned(cfg_getint(buttonSection, CFG_GPIO));
        buttonsConfig->Total++;

        if(buttonsConfig->Total > SNESDEV_MAX_BUTTONS) {
            break;
        }
    }

    cfg_free(cfg);

    if(!ValidateConfig(config)) {
        return false;
    }

    return true;
}
예제 #22
0
Error ValidateCreateContext(Display *display, Config *configuration, gl::Context *shareContext,
                            const AttributeMap& attributes)
{
    ANGLE_TRY(ValidateConfig(display, configuration));

    // Get the requested client version (default is 1) and check it is 2 or 3.
    EGLAttrib clientMajorVersion = 1;
    EGLAttrib clientMinorVersion = 0;
    EGLAttrib contextFlags       = 0;
    bool resetNotification = false;
    bool robustAccess = false;
    for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
    {
        EGLAttrib attribute = attributeIter->first;
        EGLAttrib value     = attributeIter->second;

        switch (attribute)
        {
        case EGL_CONTEXT_CLIENT_VERSION:
            clientMajorVersion = value;
            break;

        case EGL_CONTEXT_MINOR_VERSION:
            clientMinorVersion = value;
            break;

        case EGL_CONTEXT_FLAGS_KHR:
            contextFlags = value;
            break;

        case EGL_CONTEXT_OPENGL_DEBUG:
            break;

        case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
            // Only valid for OpenGL (non-ES) contexts
            return Error(EGL_BAD_ATTRIBUTE);

        case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
            if (!display->getExtensions().createContextRobustness)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            if (value != EGL_TRUE && value != EGL_FALSE)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            robustAccess = (value == EGL_TRUE);
            break;

        case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
            static_assert(EGL_LOSE_CONTEXT_ON_RESET_EXT == EGL_LOSE_CONTEXT_ON_RESET_KHR, "EGL extension enums not equal.");
            static_assert(EGL_NO_RESET_NOTIFICATION_EXT == EGL_NO_RESET_NOTIFICATION_KHR, "EGL extension enums not equal.");
        // same as EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, fall through
        case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
            if (!display->getExtensions().createContextRobustness)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            if (value == EGL_LOSE_CONTEXT_ON_RESET_EXT)
            {
                resetNotification = true;
            }
            else if (value != EGL_NO_RESET_NOTIFICATION_EXT)
            {
                return Error(EGL_BAD_ATTRIBUTE);
            }
            break;

        case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
            if (!display->getExtensions().createContextNoError)
            {
                return Error(EGL_BAD_ATTRIBUTE, "Invalid Context attribute.");
            }
            if (value != EGL_TRUE && value != EGL_FALSE)
            {
                return Error(EGL_BAD_ATTRIBUTE, "Attribute must be EGL_TRUE or EGL_FALSE.");
            }
            break;

        case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE:
            if (!display->getExtensions().createContextWebGLCompatibility)
            {
                return Error(EGL_BAD_ATTRIBUTE,
                             "Attribute EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE requires "
                             "EGL_ANGLE_create_context_webgl_compatibility.");
            }
            if (value != EGL_TRUE && value != EGL_FALSE)
            {
                return Error(
                           EGL_BAD_ATTRIBUTE,
                           "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE must be EGL_TRUE or EGL_FALSE.");
            }
            break;

        default:
            return Error(EGL_BAD_ATTRIBUTE);
        }
    }

    switch (clientMajorVersion)
    {
    case 2:
        if (clientMinorVersion != 0)
        {
            return Error(EGL_BAD_CONFIG);
        }
        break;
    case 3:
        if (clientMinorVersion != 0 && clientMinorVersion != 1)
        {
            return Error(EGL_BAD_CONFIG);
        }
        if (!(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR))
        {
            return Error(EGL_BAD_CONFIG);
        }
        if (display->getMaxSupportedESVersion() <
                gl::Version(static_cast<GLuint>(clientMajorVersion),
                            static_cast<GLuint>(clientMinorVersion)))
        {
            return Error(EGL_BAD_CONFIG, "Requested GLES version is not supported.");
        }
        break;
    default:
        return Error(EGL_BAD_CONFIG);
        break;
    }

    // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES
    const EGLint validContextFlags = (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR |
                                      EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
    if ((contextFlags & ~validContextFlags) != 0)
    {
        return Error(EGL_BAD_ATTRIBUTE);
    }

    if ((contextFlags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) > 0)
    {
        robustAccess = true;
    }

    if (robustAccess)
    {
        // Unimplemented
        return Error(EGL_BAD_CONFIG);
    }

    if (shareContext)
    {
        // Shared context is invalid or is owned by another display
        if (!display->isValidContext(shareContext))
        {
            return Error(EGL_BAD_MATCH);
        }

        if (shareContext->isResetNotificationEnabled() != resetNotification)
        {
            return Error(EGL_BAD_MATCH);
        }

        if (shareContext->getClientMajorVersion() != clientMajorVersion ||
                shareContext->getClientMinorVersion() != clientMinorVersion)
        {
            return Error(EGL_BAD_CONTEXT);
        }
    }

    return Error(EGL_SUCCESS);
}