zng_swgl/
swgl_fns.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4#![allow(unused_variables)]
5
6use gleam::gl::*;
7use std::ffi::{CStr, CString};
8use std::os::raw::{c_char, c_int, c_void};
9use std::ptr;
10use std::str;
11
12#[allow(unused)]
13macro_rules! debug {
14    ($($x:tt)*) => {};
15}
16
17#[repr(C)]
18struct LockedTexture {
19    _private: [u8; 0],
20}
21
22#[allow(dead_code)]
23extern "C" {
24    fn ActiveTexture(texture: GLenum);
25    fn BindTexture(target: GLenum, texture: GLuint);
26    fn BindBuffer(target: GLenum, buffer: GLuint);
27    fn BindVertexArray(vao: GLuint);
28    fn BindFramebuffer(target: GLenum, fb: GLuint);
29    fn BindRenderbuffer(target: GLenum, rb: GLuint);
30    fn BlendFunc(srgb: GLenum, drgb: GLenum, sa: GLenum, da: GLenum);
31    fn BlendColor(r: GLfloat, g: GLfloat, b: GLfloat, a: GLfloat);
32    fn BlendEquation(mode: GLenum);
33    fn Enable(cap: GLenum);
34    fn Disable(cap: GLenum);
35    fn GenQueries(n: GLsizei, result: *mut GLuint);
36    fn BeginQuery(target: GLenum, id: GLuint);
37    fn EndQuery(target: GLenum);
38    fn GetQueryObjectui64v(id: GLuint, pname: GLenum, params: *mut GLuint64);
39    fn GenBuffers(n: i32, result: *mut GLuint);
40    fn GenTextures(n: i32, result: *mut GLuint);
41    fn GenFramebuffers(n: i32, result: *mut GLuint);
42    fn GenRenderbuffers(n: i32, result: *mut GLuint);
43    fn BufferData(target: GLenum, size: GLsizeiptr, data: *const GLvoid, usage: GLenum);
44    fn BufferSubData(target: GLenum, offset: GLintptr, size: GLsizeiptr, data: *const GLvoid);
45    fn MapBuffer(target: GLenum, access: GLbitfield) -> *mut c_void;
46    fn MapBufferRange(
47        target: GLenum,
48        offset: GLintptr,
49        length: GLsizeiptr,
50        access: GLbitfield,
51    ) -> *mut c_void;
52    fn UnmapBuffer(target: GLenum) -> GLboolean;
53    fn TexStorage2D(
54        target: GLenum,
55        levels: GLint,
56        internal_format: GLenum,
57        width: GLsizei,
58        height: GLsizei,
59    );
60    fn FramebufferTexture2D(
61        target: GLenum,
62        attachment: GLenum,
63        textarget: GLenum,
64        texture: GLuint,
65        level: GLint,
66    );
67    fn CheckFramebufferStatus(target: GLenum) -> GLenum;
68    fn InvalidateFramebuffer(target: GLenum, num_attachments: GLsizei, attachments: *const GLenum);
69    fn TexImage2D(
70        target: GLenum,
71        level: GLint,
72        internal_format: GLint,
73        width: GLsizei,
74        height: GLsizei,
75        border: GLint,
76        format: GLenum,
77        ty: GLenum,
78        data: *const c_void,
79    );
80    fn TexSubImage2D(
81        target: GLenum,
82        level: GLint,
83        xoffset: GLint,
84        yoffset: GLint,
85        width: GLsizei,
86        height: GLsizei,
87        format: GLenum,
88        ty: GLenum,
89        data: *const c_void,
90    );
91    fn GenerateMipmap(target: GLenum);
92    fn GetUniformLocation(program: GLuint, name: *const GLchar) -> GLint;
93    fn BindAttribLocation(program: GLuint, index: GLuint, name: *const GLchar);
94    fn GetAttribLocation(program: GLuint, name: *const GLchar) -> GLint;
95    fn GenVertexArrays(n: i32, result: *mut GLuint);
96    fn VertexAttribPointer(
97        index: GLuint,
98        size: GLint,
99        type_: GLenum,
100        normalized: GLboolean,
101        stride: GLsizei,
102        offset: *const GLvoid,
103    );
104    fn VertexAttribIPointer(
105        index: GLuint,
106        size: GLint,
107        type_: GLenum,
108        stride: GLsizei,
109        offset: *const GLvoid,
110    );
111    fn CreateShader(shader_type: GLenum) -> GLuint;
112    fn AttachShader(program: GLuint, shader: GLuint);
113    fn CreateProgram() -> GLuint;
114    fn Uniform1i(location: GLint, v0: GLint);
115    fn Uniform4fv(location: GLint, count: GLsizei, value: *const GLfloat);
116    fn UniformMatrix4fv(
117        location: GLint,
118        count: GLsizei,
119        transpose: GLboolean,
120        value: *const GLfloat,
121    );
122    fn DrawElementsInstanced(
123        mode: GLenum,
124        count: GLsizei,
125        type_: GLenum,
126        indices: GLintptr,
127        instancecount: GLsizei,
128    );
129    fn EnableVertexAttribArray(index: GLuint);
130    fn VertexAttribDivisor(index: GLuint, divisor: GLuint);
131    fn LinkProgram(program: GLuint);
132    fn GetLinkStatus(program: GLuint) -> GLint;
133    fn UseProgram(program: GLuint);
134    fn SetViewport(x: GLint, y: GLint, width: GLsizei, height: GLsizei);
135    fn FramebufferRenderbuffer(
136        target: GLenum,
137        attachment: GLenum,
138        renderbuffertarget: GLenum,
139        renderbuffer: GLuint,
140    );
141    fn RenderbufferStorage(target: GLenum, internalformat: GLenum, width: GLsizei, height: GLsizei);
142    fn DepthMask(flag: GLboolean);
143    fn DepthFunc(func: GLenum);
144    fn SetScissor(x: GLint, y: GLint, width: GLsizei, height: GLsizei);
145    fn ClearColor(r: GLfloat, g: GLfloat, b: GLfloat, a: GLfloat);
146    fn ClearDepth(depth: GLdouble);
147    fn Clear(mask: GLbitfield);
148    fn ClearTexSubImage(
149        target: GLenum,
150        level: GLint,
151        xoffset: GLint,
152        yoffset: GLint,
153        zoffset: GLint,
154        width: GLsizei,
155        height: GLsizei,
156        depth: GLsizei,
157        format: GLenum,
158        ty: GLenum,
159        data: *const c_void,
160    );
161    fn ClearTexImage(target: GLenum, level: GLint, format: GLenum, ty: GLenum, data: *const c_void);
162    fn ClearColorRect(
163        fbo: GLuint,
164        xoffset: GLint,
165        yoffset: GLint,
166        width: GLsizei,
167        height: GLsizei,
168        r: GLfloat,
169        g: GLfloat,
170        b: GLfloat,
171        a: GLfloat,
172    );
173    fn PixelStorei(name: GLenum, param: GLint);
174    fn ReadPixels(
175        x: GLint,
176        y: GLint,
177        width: GLsizei,
178        height: GLsizei,
179        format: GLenum,
180        ty: GLenum,
181        data: *mut c_void,
182    );
183    fn Finish();
184    fn ShaderSourceByName(shader: GLuint, name: *const GLchar);
185    fn TexParameteri(target: GLenum, pname: GLenum, param: GLint);
186    fn CopyImageSubData(
187        src_name: GLuint,
188        src_target: GLenum,
189        src_level: GLint,
190        src_x: GLint,
191        src_y: GLint,
192        src_z: GLint,
193        dst_name: GLuint,
194        dst_target: GLenum,
195        dst_level: GLint,
196        dst_x: GLint,
197        dst_y: GLint,
198        dst_z: GLint,
199        src_width: GLsizei,
200        src_height: GLsizei,
201        src_depth: GLsizei,
202    );
203    fn CopyTexSubImage2D(
204        target: GLenum,
205        level: GLint,
206        xoffset: GLint,
207        yoffset: GLint,
208        x: GLint,
209        y: GLint,
210        width: GLsizei,
211        height: GLsizei,
212    );
213    fn BlitFramebuffer(
214        src_x0: GLint,
215        src_y0: GLint,
216        src_x1: GLint,
217        src_y1: GLint,
218        dst_x0: GLint,
219        dst_y0: GLint,
220        dst_x1: GLint,
221        dst_y1: GLint,
222        mask: GLbitfield,
223        filter: GLenum,
224    );
225    fn GetIntegerv(pname: GLenum, params: *mut GLint);
226    fn GetBooleanv(pname: GLenum, params: *mut GLboolean);
227    fn GetString(name: GLenum) -> *const c_char;
228    fn GetStringi(name: GLenum, index: GLuint) -> *const c_char;
229    fn GetError() -> GLenum;
230    fn InitDefaultFramebuffer(
231        x: i32,
232        y: i32,
233        width: i32,
234        height: i32,
235        stride: i32,
236        buf: *mut c_void,
237    );
238    fn GetColorBuffer(
239        fbo: GLuint,
240        flush: GLboolean,
241        width: *mut i32,
242        height: *mut i32,
243        stride: *mut i32,
244    ) -> *mut c_void;
245    fn ResolveFramebuffer(fbo: GLuint);
246    fn SetTextureBuffer(
247        tex: GLuint,
248        internal_format: GLenum,
249        width: GLsizei,
250        height: GLsizei,
251        stride: GLsizei,
252        buf: *mut c_void,
253        min_width: GLsizei,
254        min_height: GLsizei,
255    );
256    fn SetTextureParameter(tex: GLuint, pname: GLenum, param: GLint);
257    fn DeleteTexture(n: GLuint);
258    fn DeleteRenderbuffer(n: GLuint);
259    fn DeleteFramebuffer(n: GLuint);
260    fn DeleteBuffer(n: GLuint);
261    fn DeleteVertexArray(n: GLuint);
262    fn DeleteQuery(n: GLuint);
263    fn DeleteShader(shader: GLuint);
264    fn DeleteProgram(program: GLuint);
265    fn LockFramebuffer(fbo: GLuint) -> *mut LockedTexture;
266    fn LockTexture(tex: GLuint) -> *mut LockedTexture;
267    fn LockResource(resource: *mut LockedTexture);
268    fn UnlockResource(resource: *mut LockedTexture);
269    fn GetResourceBuffer(
270        resource: *mut LockedTexture,
271        width: *mut i32,
272        height: *mut i32,
273        stride: *mut i32,
274    ) -> *mut c_void;
275    fn Composite(
276        locked_dst: *mut LockedTexture,
277        locked_src: *mut LockedTexture,
278        src_x: GLint,
279        src_y: GLint,
280        src_width: GLsizei,
281        src_height: GLsizei,
282        dst_x: GLint,
283        dst_y: GLint,
284        dst_width: GLsizei,
285        dst_height: GLsizei,
286        opaque: GLboolean,
287        flip_x: GLboolean,
288        flip_y: GLboolean,
289        filter: GLenum,
290        clip_x: GLint,
291        clip_y: GLint,
292        clip_width: GLsizei,
293        clip_height: GLsizei,
294    );
295    fn CompositeYUV(
296        locked_dst: *mut LockedTexture,
297        locked_y: *mut LockedTexture,
298        locked_u: *mut LockedTexture,
299        locked_v: *mut LockedTexture,
300        color_space: YuvRangedColorSpace,
301        color_depth: GLuint,
302        src_x: GLint,
303        src_y: GLint,
304        src_width: GLsizei,
305        src_height: GLsizei,
306        dst_x: GLint,
307        dst_y: GLint,
308        dst_width: GLsizei,
309        dst_height: GLsizei,
310        flip_x: GLboolean,
311        flip_y: GLboolean,
312        clip_x: GLint,
313        clip_y: GLint,
314        clip_width: GLsizei,
315        clip_height: GLsizei,
316    );
317    fn CreateContext() -> *mut c_void;
318    fn ReferenceContext(ctx: *mut c_void);
319    fn DestroyContext(ctx: *mut c_void);
320    fn MakeCurrent(ctx: *mut c_void);
321    fn ReportMemory(ctx: *mut c_void, size_of_op: unsafe extern "C" fn(ptr: *const c_void) -> usize) -> usize;
322}
323
324#[derive(Clone, Copy)]
325pub struct Context(*mut c_void);
326
327impl Context {
328    pub fn create() -> Self {
329        Context(unsafe { CreateContext() })
330    }
331
332    pub fn reference(&self) {
333        unsafe {
334            ReferenceContext(self.0);
335        }
336    }
337
338    pub fn destroy(&self) {
339        unsafe {
340            DestroyContext(self.0);
341        }
342    }
343
344    pub fn make_current(&self) {
345        unsafe {
346            MakeCurrent(self.0);
347        }
348    }
349
350    pub fn init_default_framebuffer(
351        &self,
352        x: i32,
353        y: i32,
354        width: i32,
355        height: i32,
356        stride: i32,
357        buf: *mut c_void,
358    ) {
359        unsafe {
360            InitDefaultFramebuffer(x, y, width, height, stride, buf);
361        }
362    }
363
364    pub fn get_color_buffer(&self, fbo: GLuint, flush: bool) -> (*mut c_void, i32, i32, i32) {
365        unsafe {
366            let mut width: i32 = 0;
367            let mut height: i32 = 0;
368            let mut stride: i32 = 0;
369            let data_ptr = GetColorBuffer(
370                fbo,
371                flush as GLboolean,
372                &mut width,
373                &mut height,
374                &mut stride,
375            );
376            (data_ptr, width, height, stride)
377        }
378    }
379
380    pub fn resolve_framebuffer(&self, fbo: GLuint) {
381        unsafe {
382            ResolveFramebuffer(fbo);
383        }
384    }
385
386    pub fn clear_color_rect(
387        &self,
388        fbo: GLuint,
389        xoffset: GLint,
390        yoffset: GLint,
391        width: GLsizei,
392        height: GLsizei,
393        r: f32,
394        g: f32,
395        b: f32,
396        a: f32,
397    ) {
398        unsafe {
399            ClearColorRect(fbo, xoffset, yoffset, width, height, r, g, b, a);
400        }
401    }
402
403    pub fn set_texture_buffer(
404        &self,
405        tex: GLuint,
406        internal_format: GLenum,
407        width: GLsizei,
408        height: GLsizei,
409        stride: GLsizei,
410        buf: *mut c_void,
411        min_width: GLsizei,
412        min_height: GLsizei,
413    ) {
414        unsafe {
415            SetTextureBuffer(
416                tex,
417                internal_format,
418                width,
419                height,
420                stride,
421                buf,
422                min_width,
423                min_height,
424            );
425        }
426    }
427
428    pub fn set_texture_parameter(&self, tex: GLuint, pname: GLenum, param: GLint) {
429        unsafe {
430            SetTextureParameter(tex, pname, param);
431        }
432    }
433
434    pub fn lock_framebuffer(&self, fbo: GLuint) -> Option<LockedResource> {
435        unsafe {
436            let resource = LockFramebuffer(fbo);
437            if resource != ptr::null_mut() {
438                Some(LockedResource(resource))
439            } else {
440                None
441            }
442        }
443    }
444
445    pub fn lock_texture(&self, tex: GLuint) -> Option<LockedResource> {
446        unsafe {
447            let resource = LockTexture(tex);
448            if resource != ptr::null_mut() {
449                Some(LockedResource(resource))
450            } else {
451                None
452            }
453        }
454    }
455
456    pub fn report_memory(&self, size_of_op: unsafe extern "C" fn(ptr: *const c_void) -> usize) -> usize {
457        unsafe { ReportMemory(self.0, size_of_op) }
458    }
459}
460
461impl From<*mut c_void> for Context {
462    fn from(ptr: *mut c_void) -> Self {
463        Context(ptr)
464    }
465}
466
467impl From<Context> for *mut c_void {
468    fn from(ctx: Context) -> Self {
469        ctx.0
470    }
471}
472
473fn calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum) -> usize {
474    let colors = match format {
475        RED => 1,
476        RGB => 3,
477        BGR => 3,
478
479        RGBA => 4,
480        BGRA => 4,
481
482        ALPHA => 1,
483        R16 => 1,
484        LUMINANCE => 1,
485        DEPTH_COMPONENT => 1,
486        _ => panic!("unsupported format for read_pixels: {:?}", format),
487    };
488    let depth = match pixel_type {
489        UNSIGNED_BYTE => 1,
490        UNSIGNED_SHORT => 2,
491        SHORT => 2,
492        FLOAT => 4,
493        UNSIGNED_INT_8_8_8_8_REV => 1,
494        _ => panic!("unsupported pixel_type for read_pixels: {:?}", pixel_type),
495    };
496
497    return (width * height * colors * depth) as usize;
498}
499
500impl Gl for Context {
501    fn get_type(&self) -> GlType {
502        GlType::Gl
503    }
504
505    fn buffer_data_untyped(
506        &self,
507        target: GLenum,
508        size: GLsizeiptr,
509        data: *const GLvoid,
510        usage: GLenum,
511    ) {
512        debug!(
513            "buffer_data_untyped {} {} {:?} {}",
514            target, size, data, usage
515        );
516        //panic!();
517        unsafe {
518            BufferData(target, size, data, usage);
519        }
520    }
521
522    fn buffer_sub_data_untyped(
523        &self,
524        target: GLenum,
525        offset: isize,
526        size: GLsizeiptr,
527        data: *const GLvoid,
528    ) {
529        debug!(
530            "buffer_sub_data_untyped {} {} {} {:?}",
531            target, offset, size, data
532        );
533        //panic!();
534        unsafe {
535            BufferSubData(target, offset, size, data);
536        }
537    }
538
539    fn map_buffer(&self, target: GLenum, access: GLbitfield) -> *mut c_void {
540        unsafe { MapBuffer(target, access) }
541    }
542
543    fn map_buffer_range(
544        &self,
545        target: GLenum,
546        offset: GLintptr,
547        length: GLsizeiptr,
548        access: GLbitfield,
549    ) -> *mut c_void {
550        unsafe { MapBufferRange(target, offset, length, access) }
551    }
552
553    fn unmap_buffer(&self, target: GLenum) -> GLboolean {
554        unsafe { UnmapBuffer(target) }
555    }
556
557    fn shader_source(&self, shader: GLuint, strings: &[&[u8]]) {
558        //panic!();
559        debug!("shader_source {}", shader);
560        //for s in strings {
561        //    debug!("{}", str::from_utf8(s).unwrap());
562        //}
563        //panic!();
564        for s in strings {
565            let u = str::from_utf8(s).unwrap();
566            const PREFIX: &'static str = "// shader: ";
567            if let Some(start) = u.find(PREFIX) {
568                if let Some(end) = u[start..].find('\n') {
569                    let name = u[start + PREFIX.len()..start + end].trim();
570                    debug!("shader name: {}", name);
571                    unsafe {
572                        let c_string = CString::new(name).unwrap();
573                        ShaderSourceByName(shader, c_string.as_ptr());
574                        return;
575                    }
576                }
577            }
578        }
579        panic!("unknown shader");
580    }
581
582    fn tex_buffer(&self, target: GLenum, internal_format: GLenum, buffer: GLuint) {
583        panic!();
584    }
585
586    fn read_buffer(&self, mode: GLenum) {
587        panic!();
588    }
589
590    fn read_pixels_into_buffer(
591        &self,
592        x: GLint,
593        y: GLint,
594        width: GLsizei,
595        height: GLsizei,
596        format: GLenum,
597        pixel_type: GLenum,
598        dst_buffer: &mut [u8],
599    ) {
600        // Assumes that the user properly allocated the size for dst_buffer.
601        assert!(calculate_length(width, height, format, pixel_type) == dst_buffer.len());
602
603        unsafe {
604            ReadPixels(
605                x,
606                y,
607                width,
608                height,
609                format,
610                pixel_type,
611                dst_buffer.as_mut_ptr() as *mut c_void,
612            );
613        }
614    }
615
616    fn read_pixels(
617        &self,
618        x: GLint,
619        y: GLint,
620        width: GLsizei,
621        height: GLsizei,
622        format: GLenum,
623        pixel_type: GLenum,
624    ) -> Vec<u8> {
625        let len = calculate_length(width, height, format, pixel_type);
626        let mut pixels: Vec<u8> = Vec::new();
627        pixels.reserve(len);
628        unsafe {
629            pixels.set_len(len);
630        }
631
632        self.read_pixels_into_buffer(
633            x,
634            y,
635            width,
636            height,
637            format,
638            pixel_type,
639            pixels.as_mut_slice(),
640        );
641
642        pixels
643    }
644
645    unsafe fn read_pixels_into_pbo(
646        &self,
647        x: GLint,
648        y: GLint,
649        width: GLsizei,
650        height: GLsizei,
651        format: GLenum,
652        pixel_type: GLenum,
653    ) {
654        ReadPixels(x, y, width, height, format, pixel_type, ptr::null_mut());
655    }
656
657    fn sample_coverage(&self, value: GLclampf, invert: bool) {
658        panic!();
659    }
660
661    fn polygon_offset(&self, factor: GLfloat, units: GLfloat) {
662        panic!();
663    }
664
665    fn pixel_store_i(&self, name: GLenum, param: GLint) {
666        //panic!();
667        debug!("pixel_store_i {:x} {}", name, param);
668        unsafe {
669            PixelStorei(name, param);
670        }
671    }
672
673    fn gen_buffers(&self, n: GLsizei) -> Vec<GLuint> {
674        //panic!();
675        let mut result = vec![0 as GLuint; n as usize];
676        unsafe {
677            GenBuffers(n, result.as_mut_ptr());
678        }
679        result
680    }
681
682    fn gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint> {
683        debug!("gen_renderbuffers {}", n);
684        //panic!();
685        let mut result = vec![0 as GLuint; n as usize];
686        unsafe {
687            GenRenderbuffers(n, result.as_mut_ptr());
688        }
689        result
690    }
691
692    fn gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint> {
693        //panic!();
694        debug!("gen_framebuffers {}", n);
695        let mut result = vec![0 as GLuint; n as usize];
696        unsafe {
697            GenFramebuffers(n, result.as_mut_ptr());
698        }
699        result
700    }
701
702    fn gen_textures(&self, n: GLsizei) -> Vec<GLuint> {
703        //panic!();
704        let mut result = vec![0 as GLuint; n as usize];
705        unsafe {
706            GenTextures(n, result.as_mut_ptr());
707        }
708        result
709    }
710
711    fn gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint> {
712        //panic!();
713        let mut result = vec![0 as GLuint; n as usize];
714        unsafe {
715            GenVertexArrays(n, result.as_mut_ptr());
716        }
717        result
718    }
719
720    fn gen_vertex_arrays_apple(&self, n: GLsizei) -> Vec<GLuint> {
721        self.gen_vertex_arrays(n)
722    }
723
724    fn gen_queries(&self, n: GLsizei) -> Vec<GLuint> {
725        let mut result = vec![0 as GLuint; n as usize];
726        unsafe {
727            GenQueries(n, result.as_mut_ptr());
728        }
729        result
730    }
731
732    fn begin_query(&self, target: GLenum, id: GLuint) {
733        unsafe {
734            BeginQuery(target, id);
735        }
736    }
737
738    fn end_query(&self, target: GLenum) {
739        unsafe {
740            EndQuery(target);
741        }
742    }
743
744    fn query_counter(&self, id: GLuint, target: GLenum) {
745        panic!();
746    }
747
748    fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32 {
749        panic!();
750        //0
751    }
752
753    fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32 {
754        panic!();
755        //0
756    }
757
758    fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64 {
759        panic!();
760        //0
761    }
762
763    fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64 {
764        let mut result = 0;
765        unsafe {
766            GetQueryObjectui64v(id, pname, &mut result);
767        }
768        result
769    }
770
771    fn delete_queries(&self, queries: &[GLuint]) {
772        unsafe {
773            for q in queries {
774                DeleteQuery(*q);
775            }
776        }
777    }
778
779    fn delete_vertex_arrays(&self, vertex_arrays: &[GLuint]) {
780        unsafe {
781            for v in vertex_arrays {
782                DeleteVertexArray(*v);
783            }
784        }
785    }
786
787    fn delete_vertex_arrays_apple(&self, vertex_arrays: &[GLuint]) {
788        self.delete_vertex_arrays(vertex_arrays)
789    }
790
791    fn delete_buffers(&self, buffers: &[GLuint]) {
792        unsafe {
793            for b in buffers {
794                DeleteBuffer(*b);
795            }
796        }
797    }
798
799    fn delete_renderbuffers(&self, renderbuffers: &[GLuint]) {
800        unsafe {
801            for r in renderbuffers {
802                DeleteRenderbuffer(*r);
803            }
804        }
805    }
806
807    fn delete_framebuffers(&self, framebuffers: &[GLuint]) {
808        unsafe {
809            for f in framebuffers {
810                DeleteFramebuffer(*f);
811            }
812        }
813    }
814
815    fn delete_textures(&self, textures: &[GLuint]) {
816        unsafe {
817            for t in textures {
818                DeleteTexture(*t);
819            }
820        }
821    }
822
823    fn framebuffer_renderbuffer(
824        &self,
825        target: GLenum,
826        attachment: GLenum,
827        renderbuffertarget: GLenum,
828        renderbuffer: GLuint,
829    ) {
830        debug!(
831            "framebufer_renderbuffer {} {} {} {}",
832            target, attachment, renderbuffertarget, renderbuffer
833        );
834        //panic!();
835        unsafe {
836            FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
837        }
838    }
839
840    fn renderbuffer_storage(
841        &self,
842        target: GLenum,
843        internalformat: GLenum,
844        width: GLsizei,
845        height: GLsizei,
846    ) {
847        debug!(
848            "renderbuffer_storage {} {} {} {}",
849            target, internalformat, width, height
850        );
851        //panic!();
852        unsafe {
853            RenderbufferStorage(target, internalformat, width, height);
854        }
855    }
856
857    fn depth_func(&self, func: GLenum) {
858        debug!("depth_func {}", func);
859        //panic!();
860        unsafe {
861            DepthFunc(func);
862        }
863    }
864
865    fn active_texture(&self, texture: GLenum) {
866        //panic!();
867        unsafe {
868            ActiveTexture(texture);
869        }
870    }
871
872    fn attach_shader(&self, program: GLuint, shader: GLuint) {
873        debug!("attach shader {} {}", program, shader);
874        //panic!();
875        unsafe {
876            AttachShader(program, shader);
877        }
878    }
879
880    fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str) {
881        debug!("bind_attrib_location {} {} {}", program, index, name);
882        //panic!();
883        let c_string = CString::new(name).unwrap();
884        unsafe { BindAttribLocation(program, index, c_string.as_ptr()) }
885    }
886
887    // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml
888    unsafe fn get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint]) {
889        panic!();
890        //assert!(!result.is_empty());
891    }
892
893    // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml
894    unsafe fn get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat]) {
895        panic!();
896        //assert!(!result.is_empty());
897    }
898
899    fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint {
900        panic!();
901        //0
902    }
903
904    fn get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint> {
905        panic!();
906        //Vec::new()
907    }
908
909    fn bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint) {
910        panic!();
911    }
912
913    fn bind_buffer_range(
914        &self,
915        target: GLenum,
916        index: GLuint,
917        buffer: GLuint,
918        offset: GLintptr,
919        size: GLsizeiptr,
920    ) {
921        panic!();
922    }
923
924    fn uniform_block_binding(
925        &self,
926        program: GLuint,
927        uniform_block_index: GLuint,
928        uniform_block_binding: GLuint,
929    ) {
930        panic!();
931    }
932
933    fn bind_buffer(&self, target: GLenum, buffer: GLuint) {
934        //panic!();
935        unsafe {
936            BindBuffer(target, buffer);
937        }
938    }
939
940    fn bind_vertex_array(&self, vao: GLuint) {
941        //panic!();
942        unsafe {
943            BindVertexArray(vao);
944        }
945    }
946
947    fn bind_vertex_array_apple(&self, vao: GLuint) {
948        self.bind_vertex_array(vao)
949    }
950
951    fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint) {
952        debug!("bind_renderbuffer {} {}", target, renderbuffer);
953        //panic!();
954        unsafe {
955            BindRenderbuffer(target, renderbuffer);
956        }
957    }
958
959    fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint) {
960        debug!("bind_framebuffer {} {}", target, framebuffer);
961        //panic!();
962        unsafe {
963            BindFramebuffer(target, framebuffer);
964        }
965    }
966
967    fn bind_vertex_buffer(
968        &self,
969        binding_index: GLuint,
970        buffer: GLuint,
971        offset: GLintptr,
972        stride: GLint,
973    ) {
974        unimplemented!("Not supported by SWGL");
975    }
976
977    fn bind_texture(&self, target: GLenum, texture: GLuint) {
978        //panic!();
979        unsafe {
980            BindTexture(target, texture);
981        }
982    }
983
984    fn draw_buffers(&self, bufs: &[GLenum]) {
985        panic!();
986        //unsafe {}
987    }
988
989    // FIXME: Does not verify buffer size -- unsafe!
990    fn tex_image_2d(
991        &self,
992        target: GLenum,
993        level: GLint,
994        internal_format: GLint,
995        width: GLsizei,
996        height: GLsizei,
997        border: GLint,
998        format: GLenum,
999        ty: GLenum,
1000        opt_data: Option<&[u8]>,
1001    ) {
1002        unsafe {
1003            let pdata = match opt_data {
1004                Some(data) => data.as_ptr() as *const GLvoid,
1005                None => ptr::null(),
1006            };
1007            TexImage2D(
1008                target,
1009                level,
1010                internal_format,
1011                width,
1012                height,
1013                border,
1014                format,
1015                ty,
1016                pdata,
1017            );
1018        }
1019    }
1020
1021    fn compressed_tex_image_2d(
1022        &self,
1023        target: GLenum,
1024        level: GLint,
1025        internal_format: GLenum,
1026        width: GLsizei,
1027        height: GLsizei,
1028        border: GLint,
1029        data: &[u8],
1030    ) {
1031        panic!();
1032    }
1033
1034    fn compressed_tex_sub_image_2d(
1035        &self,
1036        target: GLenum,
1037        level: GLint,
1038        xoffset: GLint,
1039        yoffset: GLint,
1040        width: GLsizei,
1041        height: GLsizei,
1042        format: GLenum,
1043        data: &[u8],
1044    ) {
1045        panic!();
1046    }
1047
1048    fn tex_image_3d(
1049        &self,
1050        target: GLenum,
1051        level: GLint,
1052        internal_format: GLint,
1053        width: GLsizei,
1054        height: GLsizei,
1055        depth: GLsizei,
1056        border: GLint,
1057        format: GLenum,
1058        ty: GLenum,
1059        opt_data: Option<&[u8]>,
1060    ) {
1061        panic!();
1062    }
1063
1064    fn copy_tex_image_2d(
1065        &self,
1066        target: GLenum,
1067        level: GLint,
1068        internal_format: GLenum,
1069        x: GLint,
1070        y: GLint,
1071        width: GLsizei,
1072        height: GLsizei,
1073        border: GLint,
1074    ) {
1075        panic!();
1076    }
1077
1078    fn copy_tex_sub_image_2d(
1079        &self,
1080        target: GLenum,
1081        level: GLint,
1082        xoffset: GLint,
1083        yoffset: GLint,
1084        x: GLint,
1085        y: GLint,
1086        width: GLsizei,
1087        height: GLsizei,
1088    ) {
1089        unsafe {
1090            CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
1091        }
1092    }
1093
1094    fn copy_tex_sub_image_3d(
1095        &self,
1096        target: GLenum,
1097        level: GLint,
1098        xoffset: GLint,
1099        yoffset: GLint,
1100        zoffset: GLint,
1101        x: GLint,
1102        y: GLint,
1103        width: GLsizei,
1104        height: GLsizei,
1105    ) {
1106        panic!();
1107    }
1108
1109    fn tex_sub_image_2d(
1110        &self,
1111        target: GLenum,
1112        level: GLint,
1113        xoffset: GLint,
1114        yoffset: GLint,
1115        width: GLsizei,
1116        height: GLsizei,
1117        format: GLenum,
1118        ty: GLenum,
1119        data: &[u8],
1120    ) {
1121        debug!(
1122            "tex_sub_image_2d {} {} {} {} {} {} {} {}",
1123            target, level, xoffset, yoffset, width, height, format, ty
1124        );
1125        //panic!();
1126        unsafe {
1127            TexSubImage2D(
1128                target,
1129                level,
1130                xoffset,
1131                yoffset,
1132                width,
1133                height,
1134                format,
1135                ty,
1136                data.as_ptr() as *const c_void,
1137            );
1138        }
1139    }
1140
1141    fn tex_sub_image_2d_pbo(
1142        &self,
1143        target: GLenum,
1144        level: GLint,
1145        xoffset: GLint,
1146        yoffset: GLint,
1147        width: GLsizei,
1148        height: GLsizei,
1149        format: GLenum,
1150        ty: GLenum,
1151        offset: usize,
1152    ) {
1153        debug!(
1154            "tex_sub_image_2d_pbo {} {} {} {} {} {} {} {} {}",
1155            target, level, xoffset, yoffset, width, height, format, ty, offset
1156        );
1157        //panic!();
1158        unsafe {
1159            TexSubImage2D(
1160                target,
1161                level,
1162                xoffset,
1163                yoffset,
1164                width,
1165                height,
1166                format,
1167                ty,
1168                offset as *const c_void,
1169            );
1170        }
1171    }
1172
1173    fn tex_sub_image_3d(
1174        &self,
1175        target: GLenum,
1176        level: GLint,
1177        xoffset: GLint,
1178        yoffset: GLint,
1179        zoffset: GLint,
1180        width: GLsizei,
1181        height: GLsizei,
1182        depth: GLsizei,
1183        format: GLenum,
1184        ty: GLenum,
1185        data: &[u8],
1186    ) {
1187        debug!("tex_sub_image_3d");
1188        panic!();
1189    }
1190
1191    fn tex_sub_image_3d_pbo(
1192        &self,
1193        target: GLenum,
1194        level: GLint,
1195        xoffset: GLint,
1196        yoffset: GLint,
1197        zoffset: GLint,
1198        width: GLsizei,
1199        height: GLsizei,
1200        depth: GLsizei,
1201        format: GLenum,
1202        ty: GLenum,
1203        offset: usize,
1204    ) {
1205        panic!();
1206    }
1207
1208    fn tex_storage_2d(
1209        &self,
1210        target: GLenum,
1211        levels: GLint,
1212        internal_format: GLenum,
1213        width: GLsizei,
1214        height: GLsizei,
1215    ) {
1216        //panic!();
1217        unsafe {
1218            TexStorage2D(target, levels, internal_format, width, height);
1219        }
1220    }
1221
1222    fn tex_storage_3d(
1223        &self,
1224        target: GLenum,
1225        levels: GLint,
1226        internal_format: GLenum,
1227        width: GLsizei,
1228        height: GLsizei,
1229        depth: GLsizei,
1230    ) {
1231        panic!();
1232    }
1233
1234    fn get_tex_image_into_buffer(
1235        &self,
1236        target: GLenum,
1237        level: GLint,
1238        format: GLenum,
1239        ty: GLenum,
1240        output: &mut [u8],
1241    ) {
1242        panic!();
1243    }
1244
1245    unsafe fn copy_image_sub_data(
1246        &self,
1247        src_name: GLuint,
1248        src_target: GLenum,
1249        src_level: GLint,
1250        src_x: GLint,
1251        src_y: GLint,
1252        src_z: GLint,
1253        dst_name: GLuint,
1254        dst_target: GLenum,
1255        dst_level: GLint,
1256        dst_x: GLint,
1257        dst_y: GLint,
1258        dst_z: GLint,
1259        src_width: GLsizei,
1260        src_height: GLsizei,
1261        src_depth: GLsizei,
1262    ) {
1263        CopyImageSubData(
1264            src_name, src_target, src_level, src_x, src_y, src_z, dst_name, dst_target, dst_level,
1265            dst_x, dst_y, dst_z, src_width, src_height, src_depth,
1266        );
1267    }
1268
1269    fn invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum]) {
1270        unsafe {
1271            InvalidateFramebuffer(target, attachments.len() as GLsizei, attachments.as_ptr());
1272        }
1273    }
1274
1275    fn invalidate_sub_framebuffer(
1276        &self,
1277        target: GLenum,
1278        attachments: &[GLenum],
1279        xoffset: GLint,
1280        yoffset: GLint,
1281        width: GLsizei,
1282        height: GLsizei,
1283    ) {
1284    }
1285
1286    #[inline]
1287    unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]) {
1288        //panic!();
1289        assert!(!result.is_empty());
1290        GetIntegerv(name, result.as_mut_ptr());
1291    }
1292
1293    #[inline]
1294    unsafe fn get_integer_64v(&self, name: GLenum, result: &mut [GLint64]) {
1295        panic!();
1296        //assert!(!result.is_empty());
1297    }
1298
1299    #[inline]
1300    unsafe fn get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint]) {
1301        panic!();
1302        //assert!(!result.is_empty());
1303    }
1304
1305    #[inline]
1306    unsafe fn get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64]) {
1307        panic!();
1308        //assert!(!result.is_empty());
1309    }
1310
1311    #[inline]
1312    unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]) {
1313        debug!("get_boolean_v {}", name);
1314        //panic!();
1315        assert!(!result.is_empty());
1316        GetBooleanv(name, result.as_mut_ptr());
1317    }
1318
1319    #[inline]
1320    unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]) {
1321        panic!();
1322        //assert!(!result.is_empty());
1323    }
1324
1325    fn get_framebuffer_attachment_parameter_iv(
1326        &self,
1327        target: GLenum,
1328        attachment: GLenum,
1329        pname: GLenum,
1330    ) -> GLint {
1331        panic!();
1332        //0
1333    }
1334
1335    fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint {
1336        panic!();
1337        //0
1338    }
1339
1340    fn get_tex_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint {
1341        panic!();
1342        //0
1343    }
1344
1345    fn get_tex_parameter_fv(&self, target: GLenum, pname: GLenum) -> GLfloat {
1346        panic!();
1347        //0.0
1348    }
1349
1350    fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint) {
1351        //panic!();
1352        unsafe {
1353            TexParameteri(target, pname, param);
1354        }
1355    }
1356
1357    fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat) {
1358        panic!();
1359    }
1360
1361    fn framebuffer_texture_2d(
1362        &self,
1363        target: GLenum,
1364        attachment: GLenum,
1365        textarget: GLenum,
1366        texture: GLuint,
1367        level: GLint,
1368    ) {
1369        debug!(
1370            "framebuffer_texture_2d {} {} {} {} {}",
1371            target, attachment, textarget, texture, level
1372        );
1373        //panic!();
1374        unsafe {
1375            FramebufferTexture2D(target, attachment, textarget, texture, level);
1376        }
1377    }
1378
1379    fn framebuffer_texture_layer(
1380        &self,
1381        target: GLenum,
1382        attachment: GLenum,
1383        texture: GLuint,
1384        level: GLint,
1385        layer: GLint,
1386    ) {
1387        debug!(
1388            "framebuffer_texture_layer {} {} {} {} {}",
1389            target, attachment, texture, level, layer
1390        );
1391        panic!();
1392    }
1393
1394    fn blit_framebuffer(
1395        &self,
1396        src_x0: GLint,
1397        src_y0: GLint,
1398        src_x1: GLint,
1399        src_y1: GLint,
1400        dst_x0: GLint,
1401        dst_y0: GLint,
1402        dst_x1: GLint,
1403        dst_y1: GLint,
1404        mask: GLbitfield,
1405        filter: GLenum,
1406    ) {
1407        unsafe {
1408            BlitFramebuffer(
1409                src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
1410            );
1411        }
1412    }
1413
1414    fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) {
1415        panic!();
1416    }
1417
1418    fn vertex_attrib_binding(&self, attrib_index: GLuint, binding_index: GLuint) {
1419        unimplemented!("Not supported by SWGL");
1420    }
1421
1422    fn vertex_attrib_pointer_f32(
1423        &self,
1424        index: GLuint,
1425        size: GLint,
1426        normalized: bool,
1427        stride: GLsizei,
1428        offset: GLuint,
1429    ) {
1430        panic!();
1431    }
1432
1433    fn vertex_attrib_pointer(
1434        &self,
1435        index: GLuint,
1436        size: GLint,
1437        type_: GLenum,
1438        normalized: bool,
1439        stride: GLsizei,
1440        offset: GLuint,
1441    ) {
1442        debug!(
1443            "vertex_attrib_pointer {} {} {} {} {} {}",
1444            index, size, type_, normalized, stride, offset
1445        );
1446        //panic!();
1447        unsafe {
1448            VertexAttribPointer(
1449                index,
1450                size,
1451                type_,
1452                normalized as GLboolean,
1453                stride,
1454                offset as *const GLvoid,
1455            );
1456        }
1457    }
1458
1459    fn vertex_attrib_i_pointer(
1460        &self,
1461        index: GLuint,
1462        size: GLint,
1463        type_: GLenum,
1464        stride: GLsizei,
1465        offset: GLuint,
1466    ) {
1467        debug!(
1468            "vertex_attrib_i_pointer {} {} {} {} {}",
1469            index, size, type_, stride, offset
1470        );
1471        //panic!();
1472        unsafe {
1473            VertexAttribIPointer(index, size, type_, stride, offset as *const GLvoid);
1474        }
1475    }
1476
1477    fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint) {
1478        debug!("vertex_attrib_divisor {} {}", index, divisor);
1479        //assert!(index == 0 && divisor == 0);
1480        //panic!();
1481        unsafe {
1482            VertexAttribDivisor(index, divisor);
1483        }
1484    }
1485
1486    fn vertex_attrib_format(
1487        &self,
1488        attrib_index: GLuint,
1489        size: GLint,
1490        type_: GLenum,
1491        normalized: bool,
1492        relative_offset: GLuint,
1493    ) {
1494        unimplemented!("Not supported by SWGL");
1495    }
1496
1497    fn vertex_attrib_i_format(
1498        &self,
1499        attrib_index: GLuint,
1500        size: GLint,
1501        type_: GLenum,
1502        relative_offset: GLuint,
1503    ) {
1504        unimplemented!("Not supported by SWGL");
1505    }
1506
1507    fn vertex_binding_divisor(&self, binding_index: GLuint, divisor: GLuint) {
1508        unimplemented!("Not supported by SWGL");
1509    }
1510
1511    fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
1512        debug!("viewport {} {} {} {}", x, y, width, height);
1513        //panic!();
1514        unsafe {
1515            SetViewport(x, y, width, height);
1516        }
1517    }
1518
1519    fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
1520        //panic!();
1521        unsafe {
1522            SetScissor(x, y, width, height);
1523        }
1524    }
1525
1526    fn line_width(&self, width: GLfloat) {
1527        panic!();
1528    }
1529
1530    fn use_program(&self, program: GLuint) {
1531        //panic!();
1532        unsafe {
1533            UseProgram(program);
1534        }
1535    }
1536
1537    fn validate_program(&self, program: GLuint) {
1538        panic!();
1539    }
1540
1541    fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) {
1542        unsafe {
1543            DrawElementsInstanced(mode, count, NONE, first as GLintptr, 1);
1544        }
1545    }
1546
1547    fn draw_arrays_instanced(
1548        &self,
1549        mode: GLenum,
1550        first: GLint,
1551        count: GLsizei,
1552        primcount: GLsizei,
1553    ) {
1554        unsafe {
1555            DrawElementsInstanced(mode, count, NONE, first as GLintptr, primcount);
1556        }
1557    }
1558
1559    fn draw_elements(
1560        &self,
1561        mode: GLenum,
1562        count: GLsizei,
1563        element_type: GLenum,
1564        indices_offset: GLuint,
1565    ) {
1566        debug!(
1567            "draw_elements {} {} {} {} {}",
1568            mode, count, element_type, indices_offset
1569        );
1570        //panic!();
1571        unsafe {
1572            DrawElementsInstanced(mode, count, element_type, indices_offset as GLintptr, 1);
1573        }
1574    }
1575
1576    fn draw_elements_instanced(
1577        &self,
1578        mode: GLenum,
1579        count: GLsizei,
1580        element_type: GLenum,
1581        indices_offset: GLuint,
1582        primcount: GLsizei,
1583    ) {
1584        debug!(
1585            "draw_elements_instanced {} {} {} {} {}",
1586            mode, count, element_type, indices_offset, primcount
1587        );
1588        //panic!();
1589        unsafe {
1590            DrawElementsInstanced(
1591                mode,
1592                count,
1593                element_type,
1594                indices_offset as GLintptr,
1595                primcount,
1596            );
1597        }
1598    }
1599
1600    fn blend_color(&self, r: f32, g: f32, b: f32, a: f32) {
1601        unsafe {
1602            BlendColor(r, g, b, a);
1603        }
1604    }
1605
1606    fn blend_func(&self, sfactor: GLenum, dfactor: GLenum) {
1607        unsafe {
1608            BlendFunc(sfactor, dfactor, sfactor, dfactor);
1609        }
1610    }
1611
1612    fn blend_func_separate(
1613        &self,
1614        src_rgb: GLenum,
1615        dest_rgb: GLenum,
1616        src_alpha: GLenum,
1617        dest_alpha: GLenum,
1618    ) {
1619        unsafe {
1620            BlendFunc(src_rgb, dest_rgb, src_alpha, dest_alpha);
1621        }
1622    }
1623
1624    fn blend_equation(&self, mode: GLenum) {
1625        unsafe {
1626            BlendEquation(mode);
1627        }
1628    }
1629
1630    fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum) {
1631        panic!();
1632    }
1633
1634    fn color_mask(&self, r: bool, g: bool, b: bool, a: bool) {
1635        panic!();
1636    }
1637
1638    fn cull_face(&self, mode: GLenum) {
1639        panic!();
1640    }
1641
1642    fn front_face(&self, mode: GLenum) {
1643        panic!();
1644    }
1645
1646    fn enable(&self, cap: GLenum) {
1647        debug!("enable {}", cap);
1648        //panic!();
1649        unsafe {
1650            Enable(cap);
1651        }
1652    }
1653
1654    fn disable(&self, cap: GLenum) {
1655        debug!("disable {}", cap);
1656        //panic!();
1657        unsafe {
1658            Disable(cap);
1659        }
1660    }
1661
1662    fn hint(&self, param_name: GLenum, param_val: GLenum) {
1663        panic!();
1664    }
1665
1666    fn is_enabled(&self, cap: GLenum) -> GLboolean {
1667        panic!();
1668        //0
1669    }
1670
1671    fn is_shader(&self, shader: GLuint) -> GLboolean {
1672        panic!();
1673        //0
1674    }
1675
1676    fn is_texture(&self, texture: GLenum) -> GLboolean {
1677        panic!();
1678        //0
1679    }
1680
1681    fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean {
1682        panic!();
1683        //0
1684    }
1685
1686    fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean {
1687        panic!();
1688        //0
1689    }
1690
1691    fn check_frame_buffer_status(&self, target: GLenum) -> GLenum {
1692        debug!("check_frame_buffer_status {}", target);
1693        //panic!();
1694        unsafe { CheckFramebufferStatus(target) }
1695    }
1696
1697    fn enable_vertex_attrib_array(&self, index: GLuint) {
1698        //panic!();
1699        debug!("enable_vertex_attrib_array {}", index);
1700        unsafe {
1701            EnableVertexAttribArray(index);
1702            //assert_eq!(index, 0);
1703        }
1704    }
1705
1706    fn disable_vertex_attrib_array(&self, index: GLuint) {
1707        panic!();
1708    }
1709
1710    fn uniform_1f(&self, location: GLint, v0: GLfloat) {
1711        panic!();
1712    }
1713
1714    fn uniform_1fv(&self, location: GLint, values: &[f32]) {
1715        panic!();
1716    }
1717
1718    fn uniform_1i(&self, location: GLint, v0: GLint) {
1719        debug!("uniform_1i {} {}", location, v0);
1720        //panic!();
1721        unsafe {
1722            Uniform1i(location, v0);
1723        }
1724    }
1725
1726    fn uniform_1iv(&self, location: GLint, values: &[i32]) {
1727        panic!();
1728    }
1729
1730    fn uniform_1ui(&self, location: GLint, v0: GLuint) {
1731        panic!();
1732    }
1733
1734    fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat) {
1735        panic!();
1736    }
1737
1738    fn uniform_2fv(&self, location: GLint, values: &[f32]) {
1739        panic!();
1740    }
1741
1742    fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint) {
1743        panic!();
1744    }
1745
1746    fn uniform_2iv(&self, location: GLint, values: &[i32]) {
1747        panic!();
1748    }
1749
1750    fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint) {
1751        panic!();
1752    }
1753
1754    fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat) {
1755        panic!();
1756    }
1757
1758    fn uniform_3fv(&self, location: GLint, values: &[f32]) {
1759        panic!();
1760    }
1761
1762    fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint) {
1763        panic!();
1764    }
1765
1766    fn uniform_3iv(&self, location: GLint, values: &[i32]) {
1767        panic!();
1768    }
1769
1770    fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint) {
1771        panic!();
1772    }
1773
1774    fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) {
1775        panic!();
1776    }
1777
1778    fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint) {
1779        panic!();
1780    }
1781
1782    fn uniform_4iv(&self, location: GLint, values: &[i32]) {
1783        panic!();
1784    }
1785
1786    fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint) {
1787        panic!();
1788    }
1789
1790    fn uniform_4fv(&self, location: GLint, values: &[f32]) {
1791        unsafe {
1792            Uniform4fv(location, (values.len() / 4) as GLsizei, values.as_ptr());
1793        }
1794    }
1795
1796    fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32]) {
1797        panic!();
1798    }
1799
1800    fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32]) {
1801        panic!();
1802    }
1803
1804    fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32]) {
1805        debug!("uniform_matrix_4fv {} {} {:?}", location, transpose, value);
1806        //panic!();
1807        unsafe {
1808            UniformMatrix4fv(
1809                location,
1810                (value.len() / 16) as GLsizei,
1811                transpose as GLboolean,
1812                value.as_ptr(),
1813            );
1814        }
1815    }
1816
1817    fn depth_mask(&self, flag: bool) {
1818        debug!("depth_mask {}", flag);
1819        //panic!();
1820        unsafe {
1821            DepthMask(flag as GLboolean);
1822        }
1823    }
1824
1825    fn depth_range(&self, near: f64, far: f64) {
1826        panic!();
1827    }
1828
1829    fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String) {
1830        panic!();
1831        //(0, 0, String::new())
1832    }
1833
1834    fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String) {
1835        panic!();
1836        //(0, 0, String::new())
1837    }
1838
1839    fn get_active_uniforms_iv(
1840        &self,
1841        program: GLuint,
1842        indices: Vec<GLuint>,
1843        pname: GLenum,
1844    ) -> Vec<GLint> {
1845        panic!();
1846        //Vec::new()
1847    }
1848
1849    fn get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint {
1850        panic!();
1851        //0
1852    }
1853
1854    fn get_active_uniform_block_iv(
1855        &self,
1856        program: GLuint,
1857        index: GLuint,
1858        pname: GLenum,
1859    ) -> Vec<GLint> {
1860        panic!();
1861        //Vec::new()
1862    }
1863
1864    fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String {
1865        panic!();
1866        //String::new()
1867    }
1868
1869    fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int {
1870        let name = CString::new(name).unwrap();
1871        unsafe { GetAttribLocation(program, name.as_ptr()) }
1872    }
1873
1874    fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int {
1875        panic!();
1876        //0
1877    }
1878
1879    fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int {
1880        debug!("get_uniform_location {} {}", program, name);
1881        //panic!();
1882        let name = CString::new(name).unwrap();
1883        unsafe { GetUniformLocation(program, name.as_ptr()) }
1884    }
1885
1886    fn get_program_info_log(&self, program: GLuint) -> String {
1887        debug!("get_program_info_log {}", program);
1888        String::new()
1889    }
1890
1891    #[inline]
1892    unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]) {
1893        debug!("get_program_iv {}", pname);
1894        //panic!();
1895        assert!(!result.is_empty());
1896        //#define GL_LINK_STATUS                    0x8B82
1897        if pname == 0x8b82 {
1898            result[0] = GetLinkStatus(program);
1899        }
1900    }
1901
1902    fn get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum) {
1903        panic!();
1904        //(Vec::new(), NONE)
1905    }
1906
1907    fn program_binary(&self, program: GLuint, format: GLenum, binary: &[u8]) {
1908        panic!();
1909    }
1910
1911    fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint) {
1912        panic!();
1913    }
1914
1915    #[inline]
1916    unsafe fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint]) {
1917        panic!();
1918        //assert!(!result.is_empty());
1919    }
1920
1921    #[inline]
1922    unsafe fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat]) {
1923        panic!();
1924        //assert!(!result.is_empty());
1925    }
1926
1927    fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr {
1928        panic!();
1929        //0
1930    }
1931
1932    fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint {
1933        panic!();
1934        //0
1935    }
1936
1937    fn get_shader_info_log(&self, shader: GLuint) -> String {
1938        debug!("get_shader_info_log {}", shader);
1939        //panic!();
1940        String::new()
1941    }
1942
1943    fn get_string(&self, which: GLenum) -> String {
1944        // panic!();
1945        unsafe {
1946            let llstr = GetString(which);
1947            if !llstr.is_null() {
1948                return str::from_utf8_unchecked(CStr::from_ptr(llstr).to_bytes()).to_string();
1949            } else {
1950                return "".to_string();
1951            }
1952        }
1953    }
1954
1955    fn get_string_i(&self, which: GLenum, index: GLuint) -> String {
1956        //panic!();
1957        unsafe {
1958            let llstr = GetStringi(which, index);
1959            if !llstr.is_null() {
1960                str::from_utf8_unchecked(CStr::from_ptr(llstr).to_bytes()).to_string()
1961            } else {
1962                "".to_string()
1963            }
1964        }
1965    }
1966
1967    unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]) {
1968        debug!("get_shader_iv");
1969        //panic!();
1970        assert!(!result.is_empty());
1971        if pname == 0x8B81
1972        /*gl::COMPILE_STATUS*/
1973        {
1974            result[0] = 1;
1975        }
1976    }
1977
1978    fn get_shader_precision_format(
1979        &self,
1980        _shader_type: GLuint,
1981        precision_type: GLuint,
1982    ) -> (GLint, GLint, GLint) {
1983        // gl.GetShaderPrecisionFormat is not available until OpenGL 4.1.
1984        // Fallback to OpenGL standard precissions that most desktop hardware support.
1985        match precision_type {
1986            LOW_FLOAT | MEDIUM_FLOAT | HIGH_FLOAT => {
1987                // Fallback to IEEE 754 single precision
1988                // Range: from -2^127 to 2^127
1989                // Significand precision: 23 bits
1990                (127, 127, 23)
1991            }
1992            LOW_INT | MEDIUM_INT | HIGH_INT => {
1993                // Fallback to single precision integer
1994                // Range: from -2^24 to 2^24
1995                // Precision: For integer formats this value is always 0
1996                (24, 24, 0)
1997            }
1998            _ => (0, 0, 0),
1999        }
2000    }
2001
2002    fn compile_shader(&self, shader: GLuint) {
2003        debug!("compile_shader {}", shader);
2004        //panic!();
2005    }
2006
2007    fn create_program(&self) -> GLuint {
2008        debug!("create_program");
2009        //panic!();
2010        unsafe { CreateProgram() }
2011    }
2012
2013    fn delete_program(&self, program: GLuint) {
2014        unsafe {
2015            DeleteProgram(program);
2016        }
2017    }
2018
2019    fn create_shader(&self, shader_type: GLenum) -> GLuint {
2020        debug!("create_shader {}", shader_type);
2021        //panic!();
2022        unsafe { CreateShader(shader_type) }
2023    }
2024
2025    fn delete_shader(&self, shader: GLuint) {
2026        debug!("delete_shader {}", shader);
2027        //panic!();
2028        unsafe {
2029            DeleteShader(shader);
2030        }
2031    }
2032
2033    fn detach_shader(&self, program: GLuint, shader: GLuint) {
2034        debug!("detach_shader {} {}", program, shader);
2035        //panic!();
2036    }
2037
2038    fn link_program(&self, program: GLuint) {
2039        debug!("link_program {}", program);
2040        //panic!();
2041        unsafe {
2042            LinkProgram(program);
2043        }
2044    }
2045
2046    fn clear_color(&self, r: f32, g: f32, b: f32, a: f32) {
2047        //panic!();
2048        unsafe {
2049            ClearColor(r, g, b, a);
2050        }
2051    }
2052
2053    fn clear(&self, buffer_mask: GLbitfield) {
2054        debug!("clear {}", buffer_mask);
2055        //panic!();
2056        unsafe {
2057            Clear(buffer_mask);
2058        }
2059    }
2060
2061    fn clear_depth(&self, depth: f64) {
2062        debug!("clear_depth {}", depth);
2063        //panic!();
2064        unsafe {
2065            ClearDepth(depth as GLclampd);
2066        }
2067    }
2068
2069    fn clear_stencil(&self, s: GLint) {
2070        panic!();
2071    }
2072
2073    fn flush(&self) {}
2074
2075    fn finish(&self) {
2076        unsafe {
2077            Finish();
2078        }
2079    }
2080
2081    fn get_error(&self) -> GLenum {
2082        //panic!();
2083        unsafe { GetError() }
2084    }
2085
2086    fn stencil_mask(&self, mask: GLuint) {
2087        panic!();
2088    }
2089
2090    fn stencil_mask_separate(&self, face: GLenum, mask: GLuint) {
2091        panic!();
2092    }
2093
2094    fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint) {
2095        panic!();
2096    }
2097
2098    fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint) {
2099        panic!();
2100    }
2101
2102    fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum) {
2103        panic!();
2104    }
2105
2106    fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum) {
2107        panic!();
2108    }
2109
2110    fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES) {
2111        panic!("not supported")
2112    }
2113
2114    fn egl_image_target_renderbuffer_storage_oes(&self, target: GLenum, image: GLeglImageOES) {
2115        panic!("not supported")
2116    }
2117
2118    fn generate_mipmap(&self, target: GLenum) {
2119        unsafe {
2120            GenerateMipmap(target);
2121        }
2122    }
2123
2124    fn insert_event_marker_ext(&self, message: &str) {
2125        panic!();
2126    }
2127
2128    fn push_group_marker_ext(&self, message: &str) {
2129        debug!("push group {}", message);
2130        panic!();
2131    }
2132
2133    fn pop_group_marker_ext(&self) {
2134        debug!("pop group");
2135        panic!();
2136    }
2137
2138    fn debug_message_insert_khr(
2139        &self,
2140        source: GLenum,
2141        type_: GLenum,
2142        id: GLuint,
2143        severity: GLenum,
2144        message: &str,
2145    ) {
2146        panic!();
2147    }
2148
2149    fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) {
2150        panic!();
2151    }
2152
2153    fn pop_debug_group_khr(&self) {
2154        panic!();
2155    }
2156
2157    fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync {
2158        panic!();
2159        //ptr::null()
2160    }
2161
2162    fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) -> GLenum {
2163        panic!();
2164    }
2165
2166    fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) {
2167        panic!();
2168    }
2169
2170    fn texture_range_apple(&self, target: GLenum, data: &[u8]) {
2171        panic!();
2172    }
2173
2174    fn delete_sync(&self, sync: GLsync) {
2175        panic!();
2176    }
2177
2178    fn gen_fences_apple(&self, n: GLsizei) -> Vec<GLuint> {
2179        panic!();
2180        //Vec::new()
2181    }
2182
2183    fn delete_fences_apple(&self, fences: &[GLuint]) {
2184        panic!();
2185    }
2186
2187    fn set_fence_apple(&self, fence: GLuint) {
2188        panic!();
2189    }
2190
2191    fn finish_fence_apple(&self, fence: GLuint) {
2192        panic!();
2193    }
2194
2195    fn test_fence_apple(&self, fence: GLuint) {
2196        panic!();
2197    }
2198
2199    fn test_object_apple(&self, object: GLenum, name: GLuint) -> GLboolean {
2200        panic!();
2201        //0
2202    }
2203
2204    fn finish_object_apple(&self, object: GLenum, name: GLuint) {
2205        panic!();
2206    }
2207
2208    // GL_ARB_blend_func_extended
2209    fn bind_frag_data_location_indexed(
2210        &self,
2211        program: GLuint,
2212        color_number: GLuint,
2213        index: GLuint,
2214        name: &str,
2215    ) {
2216        panic!();
2217    }
2218
2219    fn get_frag_data_index(&self, program: GLuint, name: &str) -> GLint {
2220        panic!();
2221        //-1
2222    }
2223
2224    // GL_KHR_debug
2225    fn get_debug_messages(&self) -> Vec<DebugMessage> {
2226        Vec::new()
2227    }
2228
2229    fn provoking_vertex_angle(&self, _mode: GLenum) {
2230        unimplemented!("This extension is GLES only");
2231    }
2232
2233    // GL_KHR_blend_equation_advanced
2234    fn blend_barrier_khr(&self) {
2235        // No barrier required, so nothing to do
2236    }
2237
2238    // GL_CHROMIUM_copy_texture
2239    fn copy_texture_chromium(
2240        &self,
2241        _source_id: GLuint,
2242        _source_level: GLint,
2243        _dest_target: GLenum,
2244        _dest_id: GLuint,
2245        _dest_level: GLint,
2246        _internal_format: GLint,
2247        _dest_type: GLenum,
2248        _unpack_flip_y: GLboolean,
2249        _unpack_premultiply_alpha: GLboolean,
2250        _unpack_unmultiply_alpha: GLboolean,
2251    ) {
2252        unimplemented!("This extension is GLES only");
2253    }
2254    fn copy_sub_texture_chromium(
2255        &self,
2256        _source_id: GLuint,
2257        _source_level: GLint,
2258        _dest_target: GLenum,
2259        _dest_id: GLuint,
2260        _dest_level: GLint,
2261        _x_offset: GLint,
2262        _y_offset: GLint,
2263        _x: GLint,
2264        _y: GLint,
2265        _width: GLsizei,
2266        _height: GLsizei,
2267        _unpack_flip_y: GLboolean,
2268        _unpack_premultiply_alpha: GLboolean,
2269        _unpack_unmultiply_alpha: GLboolean,
2270    ) {
2271        unimplemented!("This extension is GLES only");
2272    }
2273
2274    // GL_ANGLE_copy_texture_3d
2275    fn copy_texture_3d_angle(
2276        &self,
2277        _source_id: GLuint,
2278        _source_level: GLint,
2279        _dest_target: GLenum,
2280        _dest_id: GLuint,
2281        _dest_level: GLint,
2282        _internal_format: GLint,
2283        _dest_type: GLenum,
2284        _unpack_flip_y: GLboolean,
2285        _unpack_premultiply_alpha: GLboolean,
2286        _unpack_unmultiply_alpha: GLboolean,
2287    ) {
2288        unimplemented!("Not supported by SWGL");
2289    }
2290
2291    fn copy_sub_texture_3d_angle(
2292        &self,
2293        _source_id: GLuint,
2294        _source_level: GLint,
2295        _dest_target: GLenum,
2296        _dest_id: GLuint,
2297        _dest_level: GLint,
2298        _x_offset: GLint,
2299        _y_offset: GLint,
2300        _z_offset: GLint,
2301        _x: GLint,
2302        _y: GLint,
2303        _z: GLint,
2304        _width: GLsizei,
2305        _height: GLsizei,
2306        _depth: GLsizei,
2307        _unpack_flip_y: GLboolean,
2308        _unpack_premultiply_alpha: GLboolean,
2309        _unpack_unmultiply_alpha: GLboolean,
2310    ) {
2311        unimplemented!("Not supported by SWGL");
2312    }
2313
2314    fn buffer_storage(
2315        &self,
2316        target: GLenum,
2317        size: GLsizeiptr,
2318        data: *const GLvoid,
2319        flags: GLbitfield,
2320    ) {
2321        unimplemented!("Not supported by SWGL");
2322    }
2323
2324    fn flush_mapped_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr) {
2325        unimplemented!("Not supported by SWGL");
2326    }
2327
2328    fn start_tiling_qcom(
2329        &self,
2330        x: GLuint,
2331        y: GLuint,
2332        width: GLuint,
2333        height: GLuint,
2334        preserve_mask: GLbitfield,
2335    ) {
2336        unimplemented!("Not supported by SWGL");
2337    }
2338
2339    fn end_tiling_qcom(&self, preserve_mask: GLbitfield) {
2340        unimplemented!("Not supported by SWGL");
2341    }
2342}
2343
2344/// A resource that is intended for sharing between threads.
2345/// Locked resources such as textures or framebuffers will
2346/// not allow any further modifications while it remains
2347/// locked. The resource will be unlocked when LockedResource
2348/// is dropped.
2349pub struct LockedResource(*mut LockedTexture);
2350
2351unsafe impl Send for LockedResource {}
2352unsafe impl Sync for LockedResource {}
2353
2354#[repr(u8)]
2355pub enum YuvRangedColorSpace {
2356    Rec601Narrow = 0,
2357    Rec601Full,
2358    Rec709Narrow,
2359    Rec709Full,
2360    Rec2020Narrow,
2361    Rec2020Full,
2362    GbrIdentity,
2363}
2364
2365impl LockedResource {
2366    /// Composites from a locked resource to another locked resource. The band
2367    /// offset and height are relative to the destination rectangle and specify
2368    /// how to clip the composition into appropriate range for this band.
2369    pub fn composite(
2370        &self,
2371        locked_src: &LockedResource,
2372        src_x: GLint,
2373        src_y: GLint,
2374        src_width: GLsizei,
2375        src_height: GLsizei,
2376        dst_x: GLint,
2377        dst_y: GLint,
2378        dst_width: GLsizei,
2379        dst_height: GLsizei,
2380        opaque: bool,
2381        flip_x: bool,
2382        flip_y: bool,
2383        filter: GLenum,
2384        clip_x: GLint,
2385        clip_y: GLint,
2386        clip_width: GLsizei,
2387        clip_height: GLsizei,
2388    ) {
2389        unsafe {
2390            Composite(
2391                self.0,
2392                locked_src.0,
2393                src_x,
2394                src_y,
2395                src_width,
2396                src_height,
2397                dst_x,
2398                dst_y,
2399                dst_width,
2400                dst_height,
2401                opaque as GLboolean,
2402                flip_x as GLboolean,
2403                flip_y as GLboolean,
2404                filter,
2405                clip_x,
2406                clip_y,
2407                clip_width,
2408                clip_height,
2409            );
2410        }
2411    }
2412
2413    /// Composites from locked resources representing YUV planes
2414    pub fn composite_yuv(
2415        &self,
2416        locked_y: &LockedResource,
2417        locked_u: &LockedResource,
2418        locked_v: &LockedResource,
2419        color_space: YuvRangedColorSpace,
2420        color_depth: GLuint,
2421        src_x: GLint,
2422        src_y: GLint,
2423        src_width: GLsizei,
2424        src_height: GLsizei,
2425        dst_x: GLint,
2426        dst_y: GLint,
2427        dst_width: GLsizei,
2428        dst_height: GLsizei,
2429        flip_x: bool,
2430        flip_y: bool,
2431        clip_x: GLint,
2432        clip_y: GLint,
2433        clip_width: GLsizei,
2434        clip_height: GLsizei,
2435    ) {
2436        unsafe {
2437            CompositeYUV(
2438                self.0,
2439                locked_y.0,
2440                locked_u.0,
2441                locked_v.0,
2442                color_space,
2443                color_depth,
2444                src_x,
2445                src_y,
2446                src_width,
2447                src_height,
2448                dst_x,
2449                dst_y,
2450                dst_width,
2451                dst_height,
2452                flip_x as GLboolean,
2453                flip_y as GLboolean,
2454                clip_x,
2455                clip_y,
2456                clip_width,
2457                clip_height,
2458            );
2459        }
2460    }
2461
2462    /// Get the underlying buffer for a locked resource
2463    pub fn get_buffer(&self) -> (*mut c_void, i32, i32, i32) {
2464        unsafe {
2465            let mut width: i32 = 0;
2466            let mut height: i32 = 0;
2467            let mut stride: i32 = 0;
2468            let data_ptr = GetResourceBuffer(self.0, &mut width, &mut height, &mut stride);
2469            (data_ptr, width, height, stride)
2470        }
2471    }
2472}
2473
2474impl Clone for LockedResource {
2475    fn clone(&self) -> Self {
2476        unsafe {
2477            LockResource(self.0);
2478        }
2479        LockedResource(self.0)
2480    }
2481}
2482
2483impl Drop for LockedResource {
2484    fn drop(&mut self) {
2485        unsafe {
2486            UnlockResource(self.0);
2487        }
2488    }
2489}