Quantcast
Jump to content


Recommended Posts

Posted

2021-06-14-01-banner.jpg

The Samsung Developers team works with many companies in the mobile and gaming ecosystems. We're excited to support our partner, Arm, as they bring timely and relevant content to developers looking to build games and high-performance experiences. This Vulkan Extensions series will help developers get the most out of the new and game-changing Vulkan extensions on Samsung mobile devices.

Android is enabling a host of useful new Vulkan extensions for mobile. These new extensions are set to improve the state of graphics APIs for modern applications, enabling new use cases and changing how developers can design graphics renderers going forward. In particular, in Android R, there has been a whole set of Vulkan extensions added. These extensions will be available across various Android smartphones, including the Samsung Galaxy S21, which was recently launched on 14 January. Existing Samsung Galaxy S models, such as the Samsung Galaxy S20, also allow upgrades to Android R.

One of these new Vulkan extensions for mobile are ‘maintenance extensions’. These plug up various holes in the Vulkan specification. Mostly, a lack of these extensions can be worked around, but it is annoying for application developers to do so. Having these extensions means less friction overall, which is a very good thing.

VK_KHR_uniform_buffer_standard_layout

This extension is a quiet one, but I still feel it has a lot of impact since it removes a fundamental restriction for applications. Getting to data efficiently is the lifeblood of GPU programming.

One thing I have seen trip up developers again and again are the antiquated rules for how uniform buffers (UBO) are laid out in memory. For whatever reason, UBOs have been stuck with annoying alignment rules which go back to ancient times, yet SSBOs have nice alignment rules. Why?

As an example, let us assume we want to send an array of floats to a shader:

#version 450

layout(set = 0, binding = 0, std140) uniform UBO
{
    float values[1024];
};

layout(location = 0) out vec4 FragColor;
layout(location = 0) flat in int vIndex;

void main()
{
    FragColor = vec4(values[vIndex]);
}

If you are not used to graphics API idiosyncrasies, this looks fine, but danger lurks around the corner. Any array in a UBO will be padded out to have 16 byte elements, meaning the only way to have a tightly packed UBO is to use vec4 arrays. Somehow, legacy hardware was hardwired for this assumption. SSBOs never had this problem.

std140 vs std430

You might have run into these weird layout qualifiers in GLSL. They reference some rather old GLSL versions. std140 refers to GLSL 1.40, which was introduced in OpenGL 3.1, and it was the version uniform buffers were introduced to OpenGL.

The std140 packing rules define how variables are packed into buffers. The main quirks of std140 are:

  • Vectors are aligned to their size. Notoriously, a vec3 is aligned to 16 bytes, which have tripped up countless programmers over the years, but this is just the nature of vectors in general. Hardware tends to like aligned access to vectors.
  • Array element sizes are aligned to 16 bytes. This one makes it very wasteful to use arrays of float and vec2.

The array quirk mirrors HLSL’s cbuffer. After all, both OpenGL and D3D mapped to the same hardware. Essentially, the assumption I am making here is that hardware was only able to load 16 bytes at a time with 16 byte alignment. To extract scalars, you could always do that after the load.

std430 was introduced in GLSL 4.30 in OpenGL 4.3 and was designed to be used with SSBOs. std430 removed the array element alignment rule, which means that with std430, we can express this efficiently:

#version 450

layout(set = 0, binding = 0, std430) readonly buffer SSBO
{
    float values[1024];
};

layout(location = 0) out vec4 FragColor;
layout(location = 0) flat in int vIndex;

void main()
{
    FragColor = vec4(values[vIndex]);
}

Basically, the new extension enables std430 layout for use with UBOs as well.

#version 450
#extension GL_EXT_scalar_block_layout : require

layout(set = 0, binding = 0, std430) uniform UBO
{
    float values[1024];
};

layout(location = 0) out vec4 FragColor;
layout(location = 0) flat in int vIndex;

void main()
{
    FragColor = vec4(values[vIndex]);
}

Why not just use SSBOs then?

On some architectures, yes, that is a valid workaround. However, some architectures also have special caches which are designed specifically for UBOs. Improving memory layouts of UBOs is still valuable.

GL_EXT_scalar_block_layout?

The Vulkan GLSL extension which supports std430 UBOs goes a little further and supports the scalar layout as well. This is a completely relaxed layout scheme where alignment requirements are essentially gone, however, that requires a different Vulkan extension to work.

VK_KHR_separate_depth_stencil_layouts

Depth-stencil images are weird in general. It is natural to think of these two aspects as separate images. However, the reality is that some GPU architectures like to pack depth and stencil together into one image, especially with D24S8 formats.

Expressing image layouts with depth and stencil formats have therefore been somewhat awkward in Vulkan, especially if you want to make one aspect read-only and keep another aspect as read/write, for example.

In Vulkan 1.0, both depth and stencil needed to be in the same image layout. This means that you are either doing read-only depth-stencil or read/write depth-stencil. This was quickly identified as not being good enough for certain use cases. There are valid use cases where depth is read-only while stencil is read/write in deferred rendering for example.

Eventually, VK_KHR_maintenance2 added support for some mixed image layouts which lets us express read-only depth, read/write stencil, and vice versa:

VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR

VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR

Usually, this is good enough, but there is a significant caveat to this approach, which is that depth and stencil layouts must be specified and transitioned together. This means that it is not possible to render to a depth aspect, while transitioning the stencil aspect concurrently, since changing image layouts is a write operation. If the engine is not designed to couple depths and stencil together, it causes a lot of friction in implementation.

What this extension does is completely decouple image layouts for depth and stencil aspects and makes it possible to modify the depth or stencil image layouts in complete isolation. For example:

    VkImageMemoryBarrier barrier = {…};

Normally, we would have to specify both DEPTH and STENCIL aspects for depth-stencil images. Now, we can completely ignore what stencil is doing and only modify depth image layout.

    barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
    barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR;
    barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL;

Similarly, in VK_KHR_create_renderpass2, there are extension structures where you can specify stencil layouts separately from the depth layout if you wish.

typedef struct VkAttachmentDescriptionStencilLayout {
    VkStructureType sType;
    void*          pNext;
    VkImageLayout      stencilInitialLayout;
    VkImageLayout      stencilFinalLayout;
} VkAttachmentDescriptionStencilLayout;

typedef struct VkAttachmentReferenceStencilLayout {
    VkStructureType sType;
    void*          pNext;
    VkImageLayout  stencilLayout;
} VkAttachmentReferenceStencilLayout;

Like image memory barriers, it is possible to express layout transitions that only occur in either depth or stencil attachments.

VK_KHR_spirv_1_4

Each core Vulkan version has targeted a specific SPIR-V version. For Vulkan 1.0, we have SPIR-V 1.0. For Vulkan 1.1, we have SPIR-V 1.3, and for Vulkan 1.2 we have SPIR-V 1.5.

SPIR-V 1.4 was an interim version between Vulkan 1.1 and 1.2 which added some nice features, but the usefulness of this extension is largely meant for developers who like to target SPIR-V themselves. Developers using GLSL or HLSL might not find much use for this extension. Some highlights of SPIR-V 1.4 that I think are worth mentioning are listed here.

OpSelect between composite objects

OpSelect before SPIR-V 1.4 only supports selecting between scalars and vectors. SPIR-V 1.4 thus allows you to express this kind of code easily with a simple OpSelect:

    MyStruct s = cond ? MyStruct(1, 2, 3) : MyStruct(4, 5, 6);

OpCopyLogical

There are scenarios in high-level languages where you load a struct from a buffer and then place it in a function variable. If you have ever looked at SPIR-V code for this kind of scenario, glslang would copy each element of the struct one by one, which generates bloated SPIR-V code. This is because the struct type that lives in a buffer and a struct type for a function variable are not necessarily the same. Offset decorations are the major culprits here. Copying objects in SPIR-V only works when the types are exactly the same, not “almost the same”. OpCopyLogical fixes this problem where you can copy objects of types which are the same except for decorations.

Advanced loop control hints

SPIR-V 1.4 adds ways to express partial unrolling, how many iterations are expected, and such advanced hints, which can help a driver optimize better using knowledge it otherwise would not have. There is no way to express these in normal shading languages yet, but it does not seem difficult to add support for it.

Explicit look-up tables

Describing look-up tables was a bit awkward in SPIR-V. The natural way to do this in SPIR-V 1.3 is to declare an array with private storage scope with an initializer, access chain into it and load from it. However, there was never a way to express that a global variable is const, which relies on compilers to be a little smart. As a case study, let us see what glslang emits when using Vulkan 1.1 target environment:

#version 450

layout(location = 0) out float FragColor;
layout(location = 0) flat in int vIndex;

const float LUT[4] = float[](1.0, 2.0, 3.0, 4.0);

void main()
{
    FragColor = LUT[vIndex];
}

%float_1 = OpConstant %float 1
%float_2 = OpConstant %float 2
%float_3 = OpConstant %float 3
%float_4 = OpConstant %float 4
%16 = OpConstantComposite %_arr_float_uint_4 %float_1 %float_2 %float_3 %float_4

This is super weird code, but it is easy for compilers to promote to a LUT. If the compiler can prove there are no readers before the OpStore, and only one OpStore can statically happen, compiler can optimize it to const LUT.

%indexable = OpVariable %_ptr_Function__arr_float_uint_4 Function
OpStore %indexable %16
%24 = OpAccessChain %_ptr_Function_float %indexable %index
%25 = OpLoad %float %24

In SPIR-V 1.4, the NonWritable decoration can also be used with Private and Function storage variables. Add an initializer, and we get something that looks far more reasonable and obvious:

OpDecorate %indexable NonWritable
%16 = OpConstantComposite %_arr_float_uint_4 %float_1 %float_2 %float_3 %float_4

// Initialize an array with a constant expression and mark it as NonWritable.
// This is trivially a LUT.
%indexable = OpVariable %_ptr_Function__arr_float_uint_4 Function %16
%24 = OpAccessChain %_ptr_Function_float %indexable %index
%25 = OpLoad %float %24

VK_KHR_shader_subgroup_extended_types

This extension fixes a hole in Vulkan subgroup support. When subgroups were introduced, it was only possible to use subgroup operations on 32-bit values. However, with 16-bit arithmetic getting more popular, especially float16, there are use cases where you would want to use subgroup operations on smaller arithmetic types, making this kind of shader possible:

#version 450

// subgroupAdd
#extension GL_KHR_shader_subgroup_arithmetic : require

For FP16 arithmetic:

#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require

For subgroup operations on FP16:

#extension GL_EXT_shader_subgroup_extended_types_float16 : require

layout(location = 0) out f16vec4 FragColor;
layout(location = 0) in f16vec4 vColor;

void main()
{
    FragColor = subgroupAdd(vColor);
}

VK_KHR_imageless_framebuffer

In most engines, using VkFramebuffer objects can feel a bit awkward, since most engine abstractions are based around some idea of:

MyRenderAPI::BindRenderTargets(colorAttachments, depthStencilAttachment)

In this model, VkFramebuffer objects introduce a lot of friction, since engines would almost certainly end up with either one of two strategies:

  • Create a VkFramebuffer for every render pass, free later.
  • Maintain a hashmap of all observed attachment and render-pass combinations.

Unfortunately, there are some … reasons why VkFramebuffer exists in the first place, but VK_KHR_imageless_framebuffer at least removes the largest pain point. This is needing to know the exact VkImageViews that we are going to use before we actually start rendering.

With imageless frame buffers, we can defer the exact VkImageViews we are going to render into until vkCmdBeginRenderPass. However, the frame buffer itself still needs to know about certain metadata ahead of time. Some drivers need to know this information unfortunately.

First, we set the VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT flag in vkCreateFramebuffer. This removes the need to set pAttachments. Instead, we specify some parameters for each attachment. We pass down this structure as a pNext:

typedef struct VkFramebufferAttachmentsCreateInfo {
    VkStructureType                        sType;
    const void*                                pNext;
    uint32_t                                   attachmentImageInfoCount;
    const VkFramebufferAttachmentImageInfo*    pAttachmentImageInfos;
} VkFramebufferAttachmentsCreateInfo;

typedef struct VkFramebufferAttachmentImageInfo {
    VkStructureType   sType;
    const void*       pNext;
    VkImageCreateFlags flags;
    VkImageUsageFlags usage;
    uint32_t          width;
    uint32_t          height;
    uint32_t          layerCount;
    uint32_t          viewFormatCount;
    const VkFormat*   pViewFormats;
} VkFramebufferAttachmentImageInfo;

Essentially, we need to specify almost everything that vkCreateImage would specify. The only thing we avoid is having to know the exact image views we need to use.

To begin a render pass which uses imageless frame buffer, we pass down this struct in vkCmdBeginRenderPass instead:

typedef struct VkRenderPassAttachmentBeginInfo {
    VkStructureType   sType;
    const void*       pNext;
    uint32_t          attachmentCount;
    const VkImageView* pAttachments;
} VkRenderPassAttachmentBeginInfo;

Conclusions

Overall, I feel like this extension does not really solve the problem of having to know images up front. Knowing the resolution, usage flags of all attachments up front is basically like having to know the image views up front either way. If your engine knows all this information up-front, just not the exact image views, then this extension can be useful. The number of unique VkFramebuffer objects will likely go down as well, but otherwise, there is in my personal view room to greatly improve things.

In the next blog on the new Vulkan extensions, I explore 'legacy support extensions.'

Follow Up

Thanks to Hans-Kristian Arntzen and the team at Arm for bringing this great content to the Samsung Developers community. We hope you find this information about Vulkan extensions useful for developing your upcoming mobile games.

The Samsung Developers site has many resources for developers looking to build for and integrate with Samsung devices and services. Stay in touch with the latest news by creating a free account or by subscribing to our monthly newsletter. Visit the Marketing Resources page for information on promoting and distributing your apps and games. Finally, our developer forum is an excellent way to stay up-to-date on all things related to the Galaxy ecosystem.

View the full blog at its source



  • Replies 0
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Similar Topics

    • By Samsung Newsroom
      Samsung Electronics today announced that The Premiere 8K, the company’s flagship premium projector, has received the industry’s first 8K Association (8KA) certification for 8K projectors. This recognition underscores Samsung’s leadership in projection technology while setting a new benchmark for the industry.
       
      “The Premiere 8K receiving the industry’s first 8KA certification is a major milestone as it officially demonstrates the new potential of projector technology.” said Taeyoung Son, Executive Vice President of Visual Display Business at Samsung Electronics. “We are committed to expanding the 8K ecosystem by continuously and extensively integrating new technologies.”
       
       
      Raising the Bar for 8K Projection Standards

       
      The 8KA is a global consortium of leading technology companies dedicated to advancing the adoption and standardization of 8K technology. On Dec 10, the organization introduced its New Projector certification program for 8K projectors, a significant step in the development of the 8K ecosystem.
       
      The 8KA certification evaluates a comprehensive set of standards critical to delivering an immersive viewing experience. These include resolution (7680 x 4320), brightness, contrast and color gamut to ensure vivid detail in both highlights and shadows. The criteria also encompass high dynamic range (HDR) for enhanced visual depth, 8K upscaling to refine lower-resolution content and immersive audio capabilities that support the latest formats for synchronized, high-quality sound that matches 8K’s stunning picture quality.
       
      Samsung’s The Premiere 8K excelled across all these categories, becoming the first in the industry to receive the certification.
       
       
      Bringing Unmatched Immersion to the Home Cinema

       
      Unveiled at CES 2024, The Premiere 8K transforms home entertainment with groundbreaking features and cutting-edge technology. It is the first projector to offer 8K wireless connectivity, enabling seamless streaming without complex setups. Using ultra-short throw (UST) technology with advanced aspherical mirrors, it delivers stunning, high-resolution visuals from a short distance, eliminating the need for ceiling mounts or additional installations.
       
      The Premiere 8K is designed to deliver a truly immersive experience. With 4,500 ISO Lumens of brightness, it produces vibrant, lifelike visuals — even in well-lit spaces — while its Sound-on-Screen technology integrates the top speaker module and software algorithms for an immersive sound experience.
       
      With this 8KA certification, Samsung has reaffirmed its leadership in display innovation and further solidified its reputation as a pioneer in ultra-premium technology.
      View the full article
    • By mramnesia97
      My Samsung Smart TV's (Model Code: QE55Q80AATXXC) app window is completely broken. I'm trying to enable developer mode but as soon as I enter "Apps" the window is frozen. I cannot scroll or click on anything. I can activate to press the 123 digits, but nothing happens when I try to input 1,2,3,4,5
      I've tried resetting the TV completely, unplugged it, cleared cache and everything else I can think off.
      What could possibly cause the Apps drawer to not work and be completely frozen?
    • By Samsung Newsroom
      Samsung is expanding its partnership with Art Basel to Art Basel Miami Beach. Following the debut as Art Basel’s first-ever Official Visual Display partner in Basel, Switzerland earlier this year, complete with an immersive Collectors Lounge experience. Through this unique partnership, Samsung is also launching a new initiative with Art Basel to bring curated collections of contemporary artworks from Art Basel’s renowned exhibiting galleries exclusively to the Samsung Art Store. A new collection will be shared once a quarter with the first collection launching today.
       
      ▲ Fred Tomaselli’s Irwin’s Garden (detail) (2023) shown on The Frame by Samsung. Photo: Samsung
       
      The Samsung Art Store is available on The Frame, the best-selling lifestyle TV from Samsung that doubles as a piece of art. Subscribers around the world can experience gallery highlights from Art Basel, which joins other renowned collections such as those from The Metropolitan Museum of Art, The Museum of Modern Art and The Musée d’Orsay available on the Samsung Art Store. The latest partnership with Art Basel underscores Samsung’s commitment to making world-class art accessible to anyone with The Frame through its innovative platform. 
       
       
      Samsung Art Store Subscribers Get an Exclusive Look
      Art Basel Miami Beach is the premier global art fair of the Americas with cultural significance attracting thousands of art enthusiasts every year. For the first time, this exclusive experience is being delivered directly to the screens of millions of people through The Frame.
       
      Ahead of Art Basel Miami Beach, Samsung Art Store subscribers will have access to a curated collection of 15+ select works from Art Basel’s galleries, some of which will be displayed at the highly anticipated fair, taking place from December 6-8, 2024 at the Miami Beach Convention Center. The collection features pieces from international contemporary galleries, including James Cohan, Kasmin, moniquemeloche, mor charpentier, Nara Roesler, Roberts Projects and Tina Kim, offering subscribers a unique, front-row look at some of Art Basel’s incredible works of art.
       
      ▲ Candida Alvarez’s Mostly Clear (detail) (2023) shown on The Frame by Samsung. Photo: Samsung
       
      Founded in 1970 by gallerists from Basel, Art Basel is the world’s premier art fair for modern and contemporary art. This year in Miami Beach, Art Basel will bring together 286 leading international galleries from 38 countries to present artworks of the highest quality across all media — from painting and sculpture to photography and digital works. Art Basel will once again reaffirm its unparalleled position as a platform for discovery and encounters that drive the art world.
       
      “Art Basel’s mission is to power the world of art by connecting leading artists and galleries with art loving audiences,” said Noah Horowitz, CEO of Art Basel. “Our collaboration with Samsung allows us to extend that reach like never before by broadening access to leading galleries and significant works from established artists to a new generation of emerging talents.”
       
      Yong Su Kim, EVP and Global Head of Video Services and Partnerships at Samsung, echoed the excitement surrounding this partnership. “Art Basel represents the pinnacle of contemporary art, and we are thrilled to amplify that experience with leading display technology that brings art to millions of people,” Kim said. “Through the Samsung Art Store and the lifelike visuals of The Frame, we are making it possible for anyone to experience Art Basel and take part in an iconic cultural moment.”
       
       
      Samsung Art Store Collectors Lounge to Feature Industry Panels, Interactive Activation and More
      As the Official Display Partner of Art Basel Miami Beach, Samsung is hosting a dedicated Samsung Art Store Collectors Lounge from December 4-8 under the concept, “Bringing Art Home,” where attendees can enjoy remarkable artworks on The Frame’s museum-worthy display. In addition, visitors will see The Frame showcased with unique bezels in various colors and designs from DecoTVFrames, an official Samsung partner exclusively available for The Frame.
       
      The Frame will also be installed throughout the fair to present visitors with a variety of vivid screen experiences.
       
      In addition to its dynamic Collectors Lounge experience, Samsung is hosting a series of panel discussions featuring influential voices from the contemporary art world. These sessions include:
       
      Celebrating Women in Art and Technology — Innovation and Expression
      An engaging panel led by Daria Greene, Head of Global Curation at Samsung. This discussion celebrates the journey of female artists and innovators who are redefining the intersection of art and technology. Gain insights into how digital platforms are amplifying voices and breaking new ground in contemporary art. The Future of Digital Art — Innovation, Rights and Connectivity
      Explore the future of digital art in this thought-provoking panel, moderated by Maya Harris, Head of Business Development and Strategic Partnerships at Samsung. This session delves into how technology is reshaping artistic rights, accessibility and the ways institutions and artists connect with global audiences.  
      As the home for Samsung Art Store, The Frame has been refreshed in 2024 to deliver an even more complete artistic and aesthetic experience. That includes Pantone Validated ArtfulColor Certification,1 the industry leading color experts. The Frame is the world’s first and only art TV to achieve this validation, ensuring natural and realistic visuals that wouldn’t look out of place in a gallery. It also sports an Anti-Reflection with Matte Display, helping you limit light distractions so your artwork appears even more true-to-life. The Frame hangs just like a picture flush against the wall and is available in class sizes ranging from 32 to 85 inches.
       
      The Frame also delivers value-add features that you can only find from Samsung — the #1 global TV brand for 18 years and counting.2 Samsung technology makes everything you watch look clearer and crisper, while you enjoy access to 2,700+ free channels, including 400+ premium channels on Samsung TV Plus.3 You can also game without a console through Samsung Gaming Hub,4 use your TV as your smart home hub and ensure your personal data is protected by Samsung Knox security.
       
       
      1 Pantone company provides a universal language of color, called Pantone Matching System, that enables color-critical decisions through every stage of the workflow for brands and manufacturers.
      2 Source: Omdia, Jan 2024. Results are not an endorsement of Samsung. Any reliance on these results is at the third party’s own risk.
      3 Available for free on Samsung Smart TVs released after 2016, Galaxy devices, Smart Monitors, Family Hub refrigerators and the web.
      4 Available games and content may vary by country and model and are subject to change without notice. Certain games require a separate controller. Internet connection and subscription may be required. Requires a Samsung account.
      View the full article
    • By Alex
      Three weeks ago, the company released in India the Samsung Z1, its first smartphone powered by Tizen, a homegrown alternative to Google Inc.’s Android operating system.
       
      This week, Samsung is pushing the Samsung Z1 into Bangladesh, a neighbor of India with more than 150 million people and a similarly low rate of smartphone penetration.
       
      After several missteps and rethinks, Samsung’s strategy for its Tizen smartphones is taking a clear shape: the company is aiming the fledgling platform squarely at first-time smartphone users, many of whom may not even have a bank account. The Samsung Z1 is selling in India for about $90.
       
      To that end, Samsung has been touting the “lightweight” nature of the Tizen operating system, meaning that it requires relatively little computing power and can handle most tasks without requiring pricey high-end specifications.
       
      That same lightweight approach has also allowed Samsung to use Tizen as the platform for many of the devices it is hoping will populate its “connected home,” from televisions to smart watches and home appliances.
       
      Despite concerns that Samsung’s new smartphone would face stiff competition in India, where several local handset makers are touting low-end smartphones — some of them in partnership with Google — Samsung says that its Tizen smartphones have received “positive responses” there.
       
      Positive enough, it seems, to at least push Tizen into a second country.
       
      Source: http://blogs.wsj.com/digits/2015/02/06/samsung-extends-tizen-smartphone-to-bangladesh/





×
×
  • Create New...