private void createGLCanvas()

in java/org/cef/browser/CefBrowserOsr.java [148:331]


    private void createGLCanvas() {
        GLProfile glprofile = GLProfile.getMaxFixedFunc(true);
        GLCapabilities glcapabilities = new GLCapabilities(glprofile);
        canvas_ = new GLCanvas(glcapabilities) {
            private Method scaleFactorAccessor = null;
            private boolean removed_ = true;

            @Override
            public void paint(Graphics g) {
                createBrowserIfRequired(true);
                if (g instanceof Graphics2D) {
                    GraphicsConfiguration config = ((Graphics2D) g).getDeviceConfiguration();
                    depth = config.getColorModel().getPixelSize();
                    depth_per_component = config.getColorModel().getComponentSize()[0];

                    if (OS.isMacintosh()
                            && System.getProperty("java.runtime.version").startsWith("1.8")) {
                        // This fixes a weird thing on MacOS: the scale factor being read from
                        // getTransform().getScaleX() is incorrect for Java 8 VMs; it is always
                        // 1, even though Retina display scaling of window sizes etc. is
                        // definitely ongoing somewhere in the lower levels of AWT. This isn't
                        // too big of a problem for us, because the transparent scaling handles
                        // the situation, except for one thing: the screenshot-grabbing
                        // code below, which reads from the OpenGL context, must know the real
                        // scale factor, because the image to be read is larger by that factor
                        // and thus a bigger buffer is required. This is why there's some
                        // admittedly-ugly reflection magic going on below that's able to get
                        // the real scale factor.
                        // All of this is not relevant for either Windows or MacOS JDKs > 8,
                        // for which the official "getScaleX()" approach works fine.
                        try {
                            if (scaleFactorAccessor == null) {
                                scaleFactorAccessor = getClass()
                                                              .getClassLoader()
                                                              .loadClass("sun.awt.CGraphicsDevice")
                                                              .getDeclaredMethod("getScaleFactor");
                            }
                            Object factor = scaleFactorAccessor.invoke(config.getDevice());
                            if (factor instanceof Integer) {
                                scaleFactor_ = ((Integer) factor).doubleValue();
                            } else {
                                scaleFactor_ = 1.0;
                            }
                        } catch (InvocationTargetException | IllegalAccessException
                                | IllegalArgumentException | NoSuchMethodException
                                | SecurityException | ClassNotFoundException exc) {
                            scaleFactor_ = 1.0;
                        }
                    } else {
                        scaleFactor_ = ((Graphics2D) g).getTransform().getScaleX();
                    }
                }
                super.paint(g);
            }

            @Override
            public void addNotify() {
                super.addNotify();
                if (removed_) {
                    notifyAfterParentChanged();
                    removed_ = false;
                }
            }

            @Override
            public void removeNotify() {
                if (!removed_) {
                    if (!isClosed()) {
                        notifyAfterParentChanged();
                    }
                    removed_ = true;
                }
                super.removeNotify();
            }
        };

        // The GLContext will be re-initialized when changing displays, resulting in calls to
        // dispose/init/reshape.
        canvas_.addGLEventListener(new GLEventListener() {
            @Override
            public void reshape(
                    GLAutoDrawable glautodrawable, int x, int y, int width, int height) {
                browser_rect_.setBounds(canvas_.getBounds()/*x, y, width, height*/); // [tav] todo: revise it
                screenPoint_ = canvas_.getLocationOnScreen();
                wasResized(width, height);
            }

            @Override
            public void init(GLAutoDrawable glautodrawable) {
                renderer_.initialize(glautodrawable.getGL().getGL2());
            }

            @Override
            public void dispose(GLAutoDrawable glautodrawable) {
                renderer_.cleanup(glautodrawable.getGL().getGL2());
            }

            @Override
            public void display(GLAutoDrawable glautodrawable) {
                renderer_.render(glautodrawable.getGL().getGL2());
            }
        });

        canvas_.addMouseListener(new MouseListener() {
            @Override
            public void mousePressed(MouseEvent e) {
                sendMouseEvent(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                sendMouseEvent(e);
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                sendMouseEvent(e);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                sendMouseEvent(e);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                sendMouseEvent(e);
            }
        });

        canvas_.addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseMoved(MouseEvent e) {
                sendMouseEvent(e);
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                sendMouseEvent(e);
            }
        });

        canvas_.addMouseWheelListener(new MouseWheelListener() {
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                sendMouseWheelEvent(e);
            }
        });

        canvas_.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
                sendKeyEvent(e);
            }

            @Override
            public void keyPressed(KeyEvent e) {
                sendKeyEvent(e);
            }

            @Override
            public void keyReleased(KeyEvent e) {
                sendKeyEvent(e);
            }
        });

        canvas_.setFocusable(true);
        canvas_.addFocusListener(new FocusListener() {
            @Override
            public void focusLost(FocusEvent e) {
                setFocus(false);
            }

            @Override
            public void focusGained(FocusEvent e) {
                // Dismiss any Java menus that are currently displayed.
                MenuSelectionManager.defaultManager().clearSelectedPath();
                setFocus(true);
            }
        });

        // Connect the Canvas with a drag and drop listener.
        new DropTarget(canvas_, new CefDropTargetListener(this));
    }