brandonborkholder / glg2d Goto Github PK
View Code? Open in Web Editor NEWGraphics2D wrapper for JOGL
Graphics2D wrapper for JOGL
GLG2D is an effort to translate Graphics2D calls directly into OpenGL calls and accelerate the Java2D drawing functionality. The existing OpenGL pipeline in the Oracle JVM is minimal at best and doesn't use higher-level OpenGL primitives, like GL_POLYGON and GLU tesselation that make drawing in OpenGL so fast. Find more information on http://brandonborkholder.github.com/glg2d/ Use cases: * use as a drop-in replacement for a JPanel and all Swing children will be accelerated * draw Swing components in an GLCanvas in your existing application This library is licensed under the Apache 2.0 license and JOGL is licensed and distributed separately. How to build This project uses maven, run mvn package to build the jar in the ./target/ dir or add the following to your pom.xml <dependency> <groupId>org.jogamp.glg2d</groupId> <artifactId>glg2d</artifactId> <version>${glg2d.version}</version> </dependency> Make sure you also add the GLG2D repository at http://brandonborkholder.github.com/glg2d/maven2/
The mavanagaiata maven plugin fails when there is no .git directory. This should not run by default.
Error when trying to run examples, (source compiles ok with java 17)
WARNING: Drawable component and children should be pure Swing: javax.swing.CellRendererPane[,0,0,0x0,invalid,hidden] does not inherit JComponent
Initial work has already been done on a shader-based pipeline, see e9db0c1. We should extend this to cover the entire functionality of java.awt.Graphics2D.
GLG2D, and seemingly every JOGL/LWJGL do not render on transparent backgrounds (backgrounds with a color alpha of less than 1F). It renders absolutely nothing, even on 0.999F, but as soon as the alpha is 1F it works as intended.
The reason this is so important is to make "overlays" which draw directly atop the desktop, which is quite common in game mods / cheats.
Here's my demo:
import org.jogamp.glg2d.GLG2DCanvas;
import javax.swing.*;
import java.awt.*;
public final class OverlayDemo extends JWindow {
private static final Dimension SCREEN_SIZE = Toolkit.getDefaultToolkit().getScreenSize();
private final JPanel frame = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(100, 100, 200, 200);
}
};
private OverlayDemo() {
setSize(SCREEN_SIZE);
setBackground(new Color(0, 0, 0, 0 /* alpha */));
frame.setSize(SCREEN_SIZE);
frame.setDoubleBuffered(true);
setContentPane(new GLG2DCanvas(frame));
setVisible(true);
new Thread(() -> {
while (!Thread.interrupted()) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}).start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(OverlayDemo::new);
}
}
Regression bug: Lines are not anti-aliased when drawing stroked shapes.
Dear Brandon,
I am developing a java2D interactive graphics application for a scientific computation program which has many points /vertices, lines, shapes etc with many mouse listeners. To improve its performance, I found your GLG2D library is the most suitable option. But the GLG2d.jar, glg2d-0.3-20130517.133836-3.jar downloaded from www.java2s.com ( glg2d-master.zip) doesn't seem as the latest.
I am not familiar with Maven to build a new latest glg2d jar from the latest repository of your source code in github web site. Please advise how to create the latest glg2d.jar file.
High appreciation and advance thanks.
Chinnaswamy
Singapore
Hey this is great, exactly what Im looking for! I have built an entire 2D games design tool in Swing, and the game itself runs in a Java2D canvas. I would love to see the performance gains I can get from swapping it over to your library.
However is there a basic tutorial that shows you how to simply replace whatever lines need to be replaced to implement this? It would be great if the code doesnt have to change much, perhaps only the imports?
Im drawin 32x32 tiles at 1920x1080, id like to see how it feels with this lib, and also do you get zooming etc since its base don OpenGL?
Any docs on how to transition from swing/java2d to this would be great, keep up the good work !!
Hi i tested to run glg2d on Armv7 hardware using the jogl rc6-beta
http://jausoft.com/blog/2012/02/27/jogamp-rc6-beta-linux-armv7-builds/
during glg2d unittesting i saw this:
Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: Not a GL2 implementation
at jogamp.opengl.es2.GLES2Impl.getGL2(GLES2Impl.java:4564)
at glg2d.G2DGLSimpleEventListener.setupMatrices(G2DGLSimpleEventListener.java:70)
I think glg2d shall not just assume it's GL2 and instead use getGL2ES1 or getGL2ES2.
Cheers
Xerxes
I tried to use maven, but got this:
Could not transfer artifact org.jogamp.glg2d:glg2d:pom:0.3-20130222.215441-2 from/to glg2d (http://brandonborkholder.github.com/glg2d/maven2/): Checksum validation failed, expected 7b1eae42bb5a592bf8111d8a293c3d7127938bb2 but is 43d433c4abd290de0e740bed6d7586a9b4fb6d2f
This could be due to a typo in :dependencies or network issues.
Exception in thread "Thread-1" clojure.lang.ExceptionInfo: Could not resolve dependencies {:exit-code 1, :suppress-msg true}
at clojure.core$ex_info.invoke(core.clj:4327)
at leiningen.core.classpath$get_dependencies.doInvoke(classpath.clj:166)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:621)
at leiningen.core.classpath$resolve_dependencies.doInvoke(classpath.clj:215)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at leiningen.core.eval$prep.invoke(eval.clj:54)
at leiningen.core.eval$eval_in_project.invoke(eval.clj:282)
at leiningen.repl$start_server.invoke(repl.clj:104)
at leiningen.repl$server$fn__6100.invoke(repl.clj:172)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:617)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1788)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:621)
at clojure.core$bound_fn_STAR_$fn__4102.doInvoke(core.clj:1810)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.sonatype.aether.resolution.DependencyResolutionException: Failed to collect dependencies for [#<Dependency org.clojure:clojure:jar:1.5.0 (compile)> #<Dependency com.taoensso:timbre:jar:1.5.2 (compile)> #<Dependency org.clojure:tools.namespace:jar:0.2.2 (compile)> #<Dependency jme:jme:jar:2013-04-01 (compile)> #<Dependency net.mikera:core.matrix:jar:0.6.0 (compile)> #<Dependency org.jogamp.glg2d:glg2d:jar:0.3-SNAPSHOT (compile)> #<Dependency javafx:javafx:jar:2.2 (compile)> #<Dependency org.thnetos:cd-client:jar:0.3.6 (compile)> #<Dependency org.clojure:tools.nrepl:jar:0.2.1 (compile)> #<Dependency clojure-complete:clojure-complete:jar:0.2.2 (compile)>]
at org.sonatype.aether.impl.internal.DefaultRepositorySystem.resolveDependencies(DefaultRepositorySystem.java:371)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
at cemerick.pomegranate.aether$resolve_dependencies_STAR_.doInvoke(aether.clj:585)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:617)
at cemerick.pomegranate.aether$resolve_dependencies.doInvoke(aether.clj:594)
at clojure.lang.RestFn.invoke(RestFn.java:2088)
at leiningen.core.classpath$get_dependencies.doInvoke(classpath.clj:157)
... 22 more
Caused by: org.sonatype.aether.collection.DependencyCollectionException: Failed to collect dependencies for [#<Dependency org.clojure:clojure:jar:1.5.0 (compile)> #<Dependency com.taoensso:timbre:jar:1.5.2 (compile)> #<Dependency org.clojure:tools.namespace:jar:0.2.2 (compile)> #<Dependency jme:jme:jar:2013-04-01 (compile)> #<Dependency net.mikera:core.matrix:jar:0.6.0 (compile)> #<Dependency org.jogamp.glg2d:glg2d:jar:0.3-SNAPSHOT (compile)> #<Dependency javafx:javafx:jar:2.2 (compile)> #<Dependency org.thnetos:cd-client:jar:0.3.6 (compile)> #<Dependency org.clojure:tools.nrepl:jar:0.2.1 (compile)> #<Dependency clojure-complete:clojure-complete:jar:0.2.2 (compile)>]
at org.sonatype.aether.impl.internal.DefaultDependencyCollector.collectDependencies(DefaultDependencyCollector.java:258)
at org.sonatype.aether.impl.internal.DefaultRepositorySystem.resolveDependencies(DefaultRepositorySystem.java:333)
... 34 more
Caused by: org.sonatype.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for org.jogamp.glg2d:glg2d:jar:0.3-SNAPSHOT
at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:296)
at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:186)
at org.sonatype.aether.impl.internal.DefaultDependencyCollector.process(DefaultDependencyCollector.java:412)
at org.sonatype.aether.impl.internal.DefaultDependencyCollector.collectDependencies(DefaultDependencyCollector.java:240)
... 35 more
Caused by: org.sonatype.aether.resolution.ArtifactResolutionException: Could not transfer artifact org.jogamp.glg2d:glg2d:pom:0.3-20130222.215441-2 from/to glg2d (http://brandonborkholder.github.com/glg2d/maven2/): Checksum validation failed, expected 7b1eae42bb5a592bf8111d8a293c3d7127938bb2 but is 43d433c4abd290de0e740bed6d7586a9b4fb6d2f
at org.sonatype.aether.impl.internal.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:538)
at org.sonatype.aether.impl.internal.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:216)
at org.sonatype.aether.impl.internal.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:193)
at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:281)
... 38 more
Caused by: org.sonatype.aether.transfer.ArtifactTransferException: Could not transfer artifact org.jogamp.glg2d:glg2d:pom:0.3-20130222.215441-2 from/to glg2d (http://brandonborkholder.github.com/glg2d/maven2/): Checksum validation failed, expected 7b1eae42bb5a592bf8111d8a293c3d7127938bb2 but is 43d433c4abd290de0e740bed6d7586a9b4fb6d2f
at org.sonatype.aether.connector.wagon.WagonRepositoryConnector$4.wrap(WagonRepositoryConnector.java:951)
at org.sonatype.aether.connector.wagon.WagonRepositoryConnector$4.wrap(WagonRepositoryConnector.java:941)
at org.sonatype.aether.connector.wagon.WagonRepositoryConnector$GetTask.run(WagonRepositoryConnector.java:669)
at org.sonatype.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:60)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
... 1 more
Caused by: org.sonatype.aether.transfer.ChecksumFailureException: Checksum validation failed, expected 7b1eae42bb5a592bf8111d8a293c3d7127938bb2 but is 43d433c4abd290de0e740bed6d7586a9b4fb6d2f
at org.sonatype.aether.connector.wagon.WagonRepositoryConnector$GetTask.verifyChecksum(WagonRepositoryConnector.java:731)
at org.sonatype.aether.connector.wagon.WagonRepositoryConnector$GetTask.run(WagonRepositoryConnector.java:618)
... 4 more
Hello, I have an application which works with BufferedImage, adding "layers" and then obtaining the final image using the following code:
BufferedImage buffer; // Current image
Graphics2D g2d = buffer.createGraphics() // Get a Graphics2D to work on this image
And then I work on it adding layers, and then dispose the Graphics2D. I do so on each layer, until I get the final image.
Is there a way to I have use the benefits from GLG2D? Since I can't even cast the Graphics2D obtained to yours GLGraphics2D. Or there is another way to work with images that I don't know yet? Thanks in advance!
I am running the UIDemo class (from tests) and it renders great, but the window doesn't seem to acknowledge any mouse events. E.g. When I click on any of the components, nothing happens. Can't select/enter text in text fields etc...
Is this a current limitation, or is there something I'm missing.
Use some code injection tool to instrument paint() calls to verify that the paints are being done with GLGraphics2D.
See http://forum.jogamp.org/useful-Java2D-bridge-td3391708i20.html#a3786990
Sometimes image cache shouldn't be cleared...
I use your nice API to easylly program 2d graphics on openGL with java (because I know a lot of Graphics2D and I like it :)), if I remove cache.clear() invoke from AbstractImageHelper.setG2D() my FPS increases (from 130 to 450, macbook retina :P).
I don't understand why you create a own WeakHashMap, Java 1.4+ already have one.
Anyways... Maybe cache cleaning could be a parameter, RenderingHint...
Hello,
It seems that there is a problem in the Texture cache (imageCache field) of the AbstractImageHelper class. It is a WeakHashMap, but when elements are removed from the Map (for example when you clear the Map), the native textures are not destroyed in the JOGL world, and you might have a memory leak.
We used the previous version with a ReferenceQueue (when you removed stale entries), but still the destroy(GL) method was never called, and when we changed the content of the image we had a continuous increase of native memory used (not Java memory of course), and finally a crash. When we took care of destroying the native memory each time a WeakEntry has become stale, then the crashes disappeared. I think that even if the structure of the code has changed, you might still have the same problem now.
Hervé
Following the example code, I wrapped my custom JComponent, which displays a video stream, into GLG2DCanvas. I call this component's repaint() method every time new video frame comes in. But it actually gets rendered only first time repaint() is called. All subsequent times I call repaint all the draw routines in the paintComponent() got ignored by the rendering pipeline despite being executed. Could you, please, suggest what might cause such behaviour?
Since glg2d requires jogl, why not put jogl inside it? Makes easier to integrate into maven by only one dependency instead of 3.
Hello Brandon. Thanks for making this library.
I've been trying to integrate it as an alternate renderer for the Piccolo2D library. Piccolo2D uses Java2d as its backend (by default), so just wrapping a Piccolo PCanvas in your GLG2DCanvas seemed like an easy way to alter the rendering pipeline (the old Agile2D library served the same purpose).
I'm running on an old laptop (Dell latitude D820), with current drivers. GlView says my card (technically a GeForce Go 7300 on Windows 7 64bit) support GL2.1, and I have been able to use the Processing library's GL backend without problems (not like I'm about to describe).
In glg2d, I have zero issues if I'm programmatically drawing shapes. Yet when I go to draw an image (specifically a BufferedImage), which Piccolo2D uses as its offscreen canvas, I get GL errors and my JFrame craps out.
I'm doing all of this from Clojure, but there's a simple self contained example over at
https://gist.github.com/joinr/788f23c22b3e613a643a97953a4b9962
It contains two small examples of building a JFrame with an icon (a JLabel with a BufferedImage as its imageicon) as the content. The second instance uses GLG2DCanvas to wrap the label, and should override the graphics2d calls. I plugged the resulting error I get from JOGL in debug mode.
This is the cause:
glTexParameterf( 0x2300, 0x2200, 3042.0): GL_INVALID_ENUM ( 1280 0x500)
Called from line 44 in
[org.jogamp.glg2d.impl.gl2.GL2ImageDrawer begin GL2ImageDrawer.java 44]
I actually had piccolo rendering an image with no problems initially, then the frame died and the JRE got a runtime error, killing the JVM. I'm curious to see if you have any ideas....
Note: I'm using glg2d "0.3-SNAPSHOT" for and jogl "2.0-rc11".
9b31484\src\test\java\glg2d\misc\SimpleTimingTests.java:[109,36] cannot find symbol
symbol : class SimplePathVisitor
location: class glg2d.misc.SimpleTimingTests
Btw im building with:
mvn clean install
is that correct?
Hello , the biggest problem on AMD Aparapi is , we don't have GPU side image.
BufferedImage on AMD Aparapi Requires image go to cpu for render.
But this is not good solution.
Can we make BufferedImage Wrapper for OpenGL side to directly communicate OpenCL without sending image to cpu back ?
here is sample from AMD :
https://code.google.com/p/aparapi/source/browse/trunk/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Life.java?r=675
But i think BufferedImage is not good solution for Java and OpenCL
maybe We can add glg2d aparapi compatible image to OpenCL ?
I m still searching the way
There is a limit of 30 in the matrix stack in most OpenGL implementations. When using Swing its current to go outside this limit, which will trigger this error. I suggest using a loadMatrix instead, and perform the matrix composition in the Java world
I wanted to comment how much I love this project! I switched over my java2d code to this and got an amazing performance boost. Thank you for creating this library!
Sometimes (this is a intermittent problem) I'm getting a NullPointerException in setComposite method of AbstractColorHelper, comp (parameter) came as null, so the notImplemented method throws the exception.
As palliative I made a check to see if comp is null.
if(comp!=null){
notImplemented("setComposite(Composite) with " + comp.getClass().getSimpleName());
}
I can't find the cause of the problem.
Caused by: java.lang.NullPointerException
at org.jogamp.glg2d.impl.AbstractColorHelper.setComposite(AbstractColorHelper.java:124)
at org.jogamp.glg2d.GLGraphics2D.setComposite(GLGraphics2D.java:311)
at org.jogamp.glg2d.impl.gl2.GL2ImageDrawer.begin(GL2ImageDrawer.java:51)
at org.jogamp.glg2d.impl.AbstractImageHelper.drawImage(AbstractImageHelper.java:124)
at org.jogamp.glg2d.GLGraphics2D.drawImage(GLGraphics2D.java:676)
VisualTest tests a pretty small subset of the Graphics2D functionality. Ideally, an automated test suite would draw using Sun's and GLG2D's renderers and then compare.
Hi All,
I could successfully made use of GLG2D library to my java2D application with all existing Mouse Listeners and Mouse Motion Listeners (of Java2D application) added to GLG2DCanvas component . In that, I also have a MousePopupListener added to GLG2DCanvas component for triggering the popping up of a JPopupMenu when mouse right button is pressed.. When I pressed the mouse right button as per the method in MousePopupListener, there was no display of JPopupMenu although I have already added,
"JPopupMenu.setDefaultLightWeightPopupEnabled(false);" in the constructor . The same Mouse Popup Listener is working well when added to JPanel added to the contentPane of JFrame.
When I tried to debug at the lines of MousePopupLisneter,when added to GLG2DCanvas the program execution does not even reach the mousePressed method.
Request for your advice to resolve this issue.
Thanks in advance.
Chinnaswamy,
Singapore
I would like to know what needs to be done to integrate this library with a NEWT Window. My particular requirements are as follows:
I had minor success integrating a GLWindow and JPanel with a single button using GLG2D, but adding more components resulted in weird drawing behavior I haven't been able to track down.
Let me know how interested you are in incorporating this feature. If it seems feasible, I most certainly can offer some assistance in its development. I doubt I'm the only person interested in seeing a solution to this problem. At the very least, I think some correspondence will bring the issues to light and create a road map for the solution.
Hello, I have an issue using the glg2d wrapper with the java full-screen exclusive mode API. Independet of which display mode I set I'm always getting a black screen. When I don't use the wrapper everything works properly. Here is my test source code:
import org.jogamp.glg2d.GLG2DCanvas;
import javax.swing.*;
import java.awt.*;
public class Fullscreen {
private static GraphicsDevice device;
private static JFrame frame;
public static void main(String[] args) {
GraphicsEnvironment gsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
device = gsEnvironment.getDefaultScreenDevice();
frame = new JFrame();
frame.setUndecorated(true);
frame.setIgnoreRepaint(true);
frame.setResizable(false);
JComponent canvas = new GLG2DCanvas(new MyRenderPane());
// JComponent canvas = new MyRenderPane();
canvas.setSize(new Dimension(1920, 1080));
frame.setContentPane(canvas);
frame.setLayout(null);
device.setFullScreenWindow(frame);
device.setDisplayMode(new DisplayMode(1920, 1080, 32, DisplayMode.REFRESH_RATE_UNKNOWN));
frame.repaint();
}
private static class MyRenderPane extends JComponent {
@Override
public void paintComponent(Graphics g) {
System.out.println("Drawing...");
g.setColor(Color.BLUE);
g.fillRect(0, 0, 200, 200);
}
}
}
What I noticed is that the paintComponent
method of my JComponent
isn't called even though I call repaint
on my JFrame
. There is no output ("Drawing...") to System.out
.
Sorry if i missed somthing, but I couldn't find any information on how glg2d behaves with that API. Is there anything special I need to take care of or is the API not supported yet?
Hello!
For an special Programm I had to write a completly new User Interface in Java. This is not based on AWT or SWING but draws the Components first in a BufferedImage and then on to the Screen.
By now this is fast because i only update the part of the screen that has changed.
But when drawing bigger or more complicated Objects it tends to get slower. So I thought I could speed it up with your Library.
It Looks very good because I dont need to change all the Code because I can use the GLGraphics2D.
But I only see how to use it in a Panel. I need to draw it Offscreen into a Buffered Image. The same Technique is used on other places to modify Video Content.
Do you see any chance to make an G2DGLImage?
Hi,
I just started experimenting using glg2d 0.5.
Do you mind putting 0.5 snapshot in your github repo ?
Or else, I'll have to use 0.3 snapshot in maven.
Thx much!
Edit:
I'm currently testing out a project in LWJGL and was considering using something like the CSSBox library to ease the burden on UI development - except that it's rendering pipeline depends on Java2D and AWT!
I'd love to be able to just create a dummy AWT Container subclass that redirects the rendering to my OpenGL context via glg2d, however right now glg2d is dependent on JOGL specifically. It seems like it should mostly be boilerplate changes (rather than logic) to be able to support both of these. All seems as if maintaining both of these rendering paths within the official repo would more easily keep feature parity between them (as opposed to forking). Any thoughts?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.