Beispiel #1
0
func handleUpload(hwnd win32.HWND, uMsg uint32, wParam, lParam uintptr) {
	id := wParam
	uploadsMu.Lock()
	u := uploads[id]
	delete(uploads, id)
	uploadsMu.Unlock()

	dc, err := win32.GetDC(hwnd)
	if err != nil {
		panic(err) // TODO handle errors
	}
	defer win32.ReleaseDC(hwnd, dc)

	u.src.preUpload(true)

	// TODO: adjust if dp is outside dst bounds, or sr is outside src bounds.
	err = blit(dc, _POINT{int32(u.dp.X), int32(u.dp.Y)}, u.src.hbitmap, &_RECT{
		Left:   int32(u.sr.Min.X),
		Top:    int32(u.sr.Min.Y),
		Right:  int32(u.sr.Max.X),
		Bottom: int32(u.sr.Max.Y),
	})
	go func() {
		u.src.postUpload()
		close(u.completion)
	}()
	if err != nil {
		panic(err) // TODO handle errors
	}
}
Beispiel #2
0
func fillSrc(hwnd win32.HWND, uMsg uint32, wParam, lParam uintptr) {
	dc, err := win32.GetDC(hwnd)
	if err != nil {
		panic(err) // TODO handle error?
	}
	defer win32.ReleaseDC(hwnd, dc)
	r := (*_RECT)(unsafe.Pointer(lParam))
	color := _COLORREF(wParam)

	// COLORREF is 0x00BBGGRR; color is 0xAARRGGBB
	color = _RGB(byte((color >> 16)), byte((color >> 8)), byte(color))
	brush, err := _CreateSolidBrush(color)
	if err != nil {
		panic(err) // TODO handle error
	}
	defer _DeleteObject(brush)
	err = _FillRect(dc, r, brush)
	if err != nil {
		panic(err) // TODO handle error
	}
}
Beispiel #3
0
func fillOver(hwnd win32.HWND, uMsg uint32, wParam, lParam uintptr) {
	dc, err := win32.GetDC(hwnd)
	if err != nil {
		panic(err) // TODO handle error
	}
	defer win32.ReleaseDC(hwnd, dc)
	r := (*_RECT)(unsafe.Pointer(lParam))
	color := _COLORREF(wParam)

	// AlphaBlend will stretch the input image (using StretchBlt's
	// COLORONCOLOR mode) to fill the output rectangle. Testing
	// this shows that the result appears to be the same as if we had
	// used a MxN bitmap instead.
	bitmap, bitvalues, err := mkbitmap(1, 1)
	if err != nil {
		panic(err) // TODO handle error
	}
	defer _DeleteObject(bitmap) // TODO handle error?
	*(*_COLORREF)(unsafe.Pointer(bitvalues)) = color
	if err = blend(dc, bitmap, r, 1, 1); err != nil {
		panic(err) // TODO handle error
	}
}
Beispiel #4
0
func createEGLSurface(hwnd syscall.Handle, w *windowImpl) error {
	var displayAttribPlatforms = [][]eglInt{
		// Default
		[]eglInt{
			_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
			_EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
			_EGL_NONE,
		},
		// Direct3D 11
		[]eglInt{
			_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
			_EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
			_EGL_NONE,
		},
		// Direct3D 9
		[]eglInt{
			_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
			_EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
			_EGL_NONE,
		},
		// Direct3D 11 with WARP
		//   https://msdn.microsoft.com/en-us/library/windows/desktop/gg615082.aspx
		[]eglInt{
			_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
			_EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
			_EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
			_EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
			_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
			_EGL_NONE,
		},
	}

	dc, err := win32.GetDC(hwnd)
	if err != nil {
		return fmt.Errorf("win32.GetDC failed: %v", err)
	}

	var display uintptr = _EGL_NO_DISPLAY
	for i, displayAttrib := range displayAttribPlatforms {
		lastTry := i == len(displayAttribPlatforms)-1

		display, _, _ = eglGetPlatformDisplayEXT.Call(
			_EGL_PLATFORM_ANGLE_ANGLE,
			uintptr(dc),
			uintptr(unsafe.Pointer(&displayAttrib[0])),
		)

		if display == _EGL_NO_DISPLAY {
			if !lastTry {
				continue
			}
			return fmt.Errorf("eglGetPlatformDisplayEXT failed: %v", eglErr())
		}

		if ret, _, _ := eglInitialize.Call(display, 0, 0); ret == 0 {
			if !lastTry {
				continue
			}
			return fmt.Errorf("eglInitialize failed: %v", eglErr())
		}
	}

	eglBindAPI.Call(_EGL_OPENGL_ES_API)
	if err := eglErr(); err != nil {
		return err
	}

	var numConfigs eglInt
	var config eglConfig
	ret, _, _ := eglChooseConfig.Call(
		display,
		uintptr(unsafe.Pointer(&rgb888[0])),
		uintptr(unsafe.Pointer(&config)),
		1,
		uintptr(unsafe.Pointer(&numConfigs)),
	)
	if ret == 0 {
		return fmt.Errorf("eglChooseConfig failed: %v", eglErr())
	}
	if numConfigs <= 0 {
		return errors.New("eglChooseConfig found no valid config")
	}

	surface, _, _ := eglCreateWindowSurface.Call(display, uintptr(config), uintptr(hwnd), 0, 0)
	if surface == _EGL_NO_SURFACE {
		return fmt.Errorf("eglCreateWindowSurface failed: %v", eglErr())
	}

	contextAttribs := [...]eglInt{
		_EGL_CONTEXT_CLIENT_VERSION, 2,
		_EGL_NONE,
	}
	context, _, _ := eglCreateContext.Call(
		display,
		uintptr(config),
		_EGL_NO_CONTEXT,
		uintptr(unsafe.Pointer(&contextAttribs[0])),
	)
	if context == _EGL_NO_CONTEXT {
		return fmt.Errorf("eglCreateContext failed: %v", eglErr())
	}

	eglSwapInterval.Call(display, 1)

	w.ctx = ctxWin32{
		ctx:     context,
		display: display,
		surface: surface,
	}

	return nil
}
Beispiel #5
0
func createEGLSurface(hwnd win32.HWND, w *windowImpl) error {
	displayAttrib := [...]eglInt{
		_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
		_EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
		_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
		_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
		_EGL_NONE,
	}

	dc, err := win32.GetDC(hwnd)
	if err != nil {
		return fmt.Errorf("win32.GetDC failed: %v", err)
	}
	display, _, _ := eglGetPlatformDisplayEXT.Call(
		_EGL_PLATFORM_ANGLE_ANGLE,
		uintptr(dc),
		uintptr(unsafe.Pointer(&displayAttrib)),
	)
	if display == _EGL_NO_DISPLAY {
		return fmt.Errorf("eglGetPlatformDisplayEXT failed: %v", eglErr())
	}
	if ret, _, _ := eglInitialize.Call(display, 0, 0); ret == 0 {
		return fmt.Errorf("eglInitialize failed: %v", eglErr())
	}

	eglBindAPI.Call(_EGL_OPENGL_ES_API)
	if err := eglErr(); err != nil {
		return err
	}

	var numConfigs eglInt
	var config eglConfig
	ret, _, _ := eglChooseConfig.Call(
		display,
		uintptr(unsafe.Pointer(&rgb888[0])),
		uintptr(unsafe.Pointer(&config)),
		1,
		uintptr(unsafe.Pointer(&numConfigs)),
	)
	if ret == 0 {
		return fmt.Errorf("eglChooseConfig failed: %v", eglErr())
	}
	if numConfigs <= 0 {
		return errors.New("eglChooseConfig found no valid config")
	}

	surface, _, _ := eglCreateWindowSurface.Call(display, uintptr(config), uintptr(hwnd), 0, 0)
	if surface == _EGL_NO_SURFACE {
		return fmt.Errorf("eglCreateWindowSurface failed: %v", eglErr())
	}

	contextAttribs := [...]eglInt{
		_EGL_CONTEXT_CLIENT_VERSION, 2,
		_EGL_NONE,
	}
	context, _, _ := eglCreateContext.Call(
		display,
		uintptr(config),
		_EGL_NO_CONTEXT,
		uintptr(unsafe.Pointer(&contextAttribs[0])),
	)
	if context == _EGL_NO_CONTEXT {
		return fmt.Errorf("eglCreateContext failed: %v", eglErr())
	}

	eglSwapInterval.Call(display, 1)

	w.ctx = ctxWin32{
		ctx:     context,
		display: display,
		surface: surface,
	}

	return nil
}