Quantcast
Channel: Intel Developer Zone Articles
Viewing all 183 articles
Browse latest View live

License Agreement for x86 Android* System Images for Android Software Development Kit (SDK)

$
0
0

Intel Corporation Internal Evaluation License Agreement for x86 Android* System Images for Android Software Development Kit (SDK)

This Internal Evaluation License Agreement (this "Agreement") is entered into by and between Intel and you (as an individual developer or a legal entity -- identified below as Recipient). Intel shall provide the Evaluation Software to Recipient as described in accordance with the Internal Evaluation License Terms and Conditions.

Definitions.

These terms shall have the following meanings:

"Intel" or "INTEL"
Intel Corporation
With an Address of:
2200 Mission College Blvd.
Santa Clara, CA 95052
Office of the General Counsel
Mail Stop: RNB-4-51
Attn: Software and Services Group Legal

"Evaluation Software"
The x86 Android* emulator system images for Android  Software Development Kit (SDK), as provided by Intel.

INTERNAL EVALUATION LICENSE TERMS AND CONDITIONS

1. DEFINITIONS.

1.1 Additional Defined Terms. "Agreement", "Evaluation Software",  "Intel", "Non-disclosure Agreement", "Recipient", and "Effective Date" shall have the meanings ascribed to them on the signature page(s) of this Agreement.

1.2 Evaluation Materials means, collectively, the Evaluation Software (in source and/or object code form) and documentation (including, without limitation, any design documents, specifications and other related materials) related to the Evaluation Software.

1.3 "Open Source Software" means any software that requires as a condition of use, modification and/or distribution of such software that such software or other software incorporated into, derived from or distributed with such software (a) be disclosed or distributed in source code form; or (b) be licensed by the user to third parties for the purpose of making and/or distributing derivative works; or (c) be redistributable at no charge. Open Source Software includes, without limitation, software licensed or distributed under any of the following licenses or distribution models, or licenses or distribution models substantially similar to any of the following: (a) GNU’s General Public License (GPL) or Lesser/Library GPL (LGPL), (b) the Artistic License (e.g., PERL), (c) the Mozilla Public License, (d) the Netscape Public License, (e) the Sun Community Source License (SCSL), (f) the Sun Industry Source License (SISL), (g) the Apache Software license and (h) the Common Public License (CPL).

1.4 "Pre-Release Materials" means "alpha" or "beta" designated pre-release features, which may not be fully functional, which Intel may substantially modify in producing any production version of the Evaluation Materials and/or is still under development by Intel and/or Intel’s suppliers.

2. PURPOSE. Intel desires to provide the Evaluation Materials to Recipient solely for Recipient's internal evaluation of the Evaluation Software and other Intel products, to evaluate the desirability of cooperating with Intel in developing products based on the Evaluation Software and/or to advise Intel as to possible modifications to the Evaluation Software. Recipient may not disclose, distribute or make commercial use of the Evaluation Materials or any modifications to the Evaluation Materials.

THE EVALUATION MATERIALS ARE PROVIDED FOR EVALUATION PURPOSES ONLY AND MAY NOT BE DISTRIBUTED BY RECIPIENT OR INCORPORATED INTO RECIPIENT’S PRODUCTS OR SOFTWARE. PLEASE CONTACT AN INTEL SALES REPRESENTATIVE TO LEARN ABOUT THE AVAILABILITY AND COST OF A COMMERICAL VERSION OF THE EVALUATION SOFTWARE.

3. TITLE. Title to the Evaluation Materials remains with Intel or its suppliers. Recipient shall not mortgage, pledge or encumber the Evaluation Materials in any way. Recipient shall return all Evaluation Materials, keeping no copies, upon termination or expiration of this Agreement.

4. LICENSE. Intel grants Recipient a royalty-free, personal, nontransferable, nonexclusive license under its copyrights to use the Evaluation Software only for the purposes described in paragraph 2 above. Unless otherwise communicated in writing by Intel to Recipient, to the extent the Evaluation Software is provided in more than one delivery or release (each, a "Release") the license grant in this Section 4 and the Evaluation Period shall apply to each Release. Recipient may not make modifications to the Evaluation Software. Recipient shall not disassemble, reverse-engineer, or decompile any software not provided to Recipient in source code form.

EXCEPT AS PROVIDED HEREIN, NO OTHER LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY OTHER INTELLECTUAL PROPERTY RIGHTS IS GRANTED TO THE RECIPIENT.

5. NO OBLIGATION. Recipient shall have no duty to purchase or license any product from Intel. Intel and its suppliers shall have no obligation to provide support for, or develop a non-evaluation version of, the Evaluation Software or to license any version of it.

6. MODIFICATIONS. This Agreement does NOT obligate Recipient to provide Intel with comments or suggestions regarding Evaluation Materials. However, should Recipient provide Intel with comments or suggestions for the modification, correction, improvement or enhancement of (a) the Evaluation Materials or (b) Intel products or processes which may embody the Evaluation Materials, Recipient grants to Intel a non-exclusive, irrevocable, worldwide, royalty-free license, with the right to sublicense Intel’s licensees and customers, under Recipient intellectual property rights, the rights to use and disclose such comments and suggestions in any manner Intel chooses and to display, perform, copy, make, have made, use, sell, offer to sell, import, and otherwise dispose of Intel’s and its sublicensee’s products embodying such comments and suggestions in any manner and via any media Intel chooses, without reference to the source.

7. WARRANTY DISCLAIMER. INTEL AND ITS SUPPLIERS MAKE NO WARRANTIES WITH RESPECT TO EVALUATION MATERIALS, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY IMPLIED WARRANTY OF NONINFRINGEMENT. THE EVALUATION MATERIALS ARE PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND.

8. LIMITATION OF LIABILITY. INTEL AND ITS SUPPLIERS SHALL NOT BE LIABLE FOR ANY PROPERTY DAMAGE, PERSONAL INJURY, LOSS OF PROFITS, INTERRUPTION OF BUSINESS OR ANY SPECIAL, CONSEQUENTIAL OR INCIDENTAL DAMAGES, HOWEVER CAUSED, WHETHER FOR BREACH OF WARRANTY, CONTRACT, STRICT LIABILITY OR OTHERWISE. INTEL AND ITS SUPPLIERS DISCLAIM ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS RELATING TO THE EVALUATION MATERIALS.

9. EXPIRATION. Intel may terminate this Agreement immediately after a breach by Recipient.

10. GENERAL.

10.1 Controlling Law. Any claims arising under or relating to this Agreement shall be governed by the internal substantive laws of the State of Delaware or federal courts located in Delaware, without regard to principles of conflict of laws. Each party hereby agrees to jurisdiction and venue in the courts of the State of Delaware for all disputes and litigation arising under or relating to this Agreement. The parties agree that the United Nations Convention on Contracts for the International Sale of Goods is specifically excluded from application to this Agreement. The parties consent to the personal jurisdiction of the above courts.

10.2 Remedies. Recipient acknowledges that any disclosure, commercialization, or public use of the Evaluation Materials would cause irreparable injury to Intel and consents to the grant of an injunction by any court of competent jurisdiction in the event of a threatened breach.

10.3 Assignment. Recipient may not delegate, assign or transfer this Agreement, the license granted or any of Recipient’s rights or duties hereunder, expressly, by implication, by operation of law, by way of merger (regardless of whether Recipient is the surviving entity) or acquisition, or otherwise and any attempt to do so, without Intel’s express prior written consent, shall be null and void. Intel may assign this Agreement, and its rights and obligations hereunder, in its sole discretion.

10.4 Entire Agreement. This Agreement constitutes the entire agreement between Recipient and Intel and supersedes in their entirety any and all oral or written agreements previously existing between Recipient and Intel with respect to the subject matter hereof. This Agreement supersedes any and all "click-to-accept" or shrink-wrapped licenses, in hard-copy or electronic form, embedded in or included with the Evaluation Materials. This Agreement may only be amended or supplemented by a writing that refers explicitly to this Agreement and that is signed by duly authorized representatives of Recipient and Intel. Without limiting the foregoing, terms and conditions on any purchase orders or similar materials submitted by Recipient to Intel, and any terms contained in Intel’s standard acknowledgment form that are in conflict with these terms, shall be of no force or effect.

10.5 Severability. In the event that any provision of this Agreement shall be unenforceable or invalid under any applicable law or be so held by applicable court decision, such unenforceability or invalidity shall not render this Agreement unenforceable or invalid as a whole, and, in such event, such provision shall be changed and interpreted so as to best accomplish the objectives of such unenforceable or invalid provision within the limits of applicable law or applicable court decisions.

10.6 Export Regulations / Export Control. Recipient shall not export, either directly or indirectly, any product, service or technical data or system incorporating the Evaluation Materials without first obtaining any required license or other approval from the U.S. Department of Commerce or any other agency or department of the United States Government. In the event any product is exported from the United States or re-exported from a foreign destination by Recipient, Recipient shall ensure that the distribution and export/re-export or import of the product is in compliance with all laws, regulations, orders, or other restrictions of the U.S. Export Administration Regulations and the appropriate foreign government. Recipient agrees that neither it nor any of its subsidiaries will export/re-export any technical data, process, product, or service, directly or indirectly, to any country for which the United States government or any agency thereof or the foreign government from where it is shipping requires an export license, or other governmental approval, without first obtaining such license or approval. Recipient also agrees to implement measures to ensure that foreign national employees are authorized to receive any information controlled by U.S. export control laws. An export is "deemed" to take place when information is released to a foreign national wherever located.

10.7 Special Terms for Pre-Release Materials. If so indicated in the description of the Evaluation Software, the Evaluation Software may contain Pre-Release Materials. Recipient hereby understands, acknowledges and agrees that: (i) Pre-Release Materials may not be fully tested and may contain bugs or errors; (ii) Pre-Release materials are not suitable for commercial release in their current state; (iii) regulatory approvals for Pre-Release Materials (such as UL or FCC) have not been obtained, and Pre-Release Materials may therefore not be certified for use in certain countries or environments and (iv) Intel can provide no assurance that it will ever produce or make generally available a production version of the Pre-Release Materials . Intel is not under any obligation to develop and/or release or offer for sale or license a final product based upon the Pre-Release Materials and may unilaterally elect to abandon the Pre-Release Materials or any such development platform at any time and without any obligation or liability whatsoever to Recipient or any other person.

10.8 Open Source Software. In the event Open Source software is included with Evaluation Software, such Open Source software is licensed pursuant to the applicable Open Source software license agreement identified in the Open Source software comments in the applicable source code file(s) and/or file header provided with Evaluation Software. Additional detail may be provided (where applicable) in the accompanying on-line documentation. With respect to the Open Source software, nothing in this Agreement limits any rights under, or grants rights that supersede, the terms of any applicable Open Source software license agreement.

ANY PRE-RELEASE MATERIALS ARE NON-QUALIFIED AND, AS SUCH, ARE PROVIDED POSSIBLY WITH FAULTS

Click to Accept EULA & Download sysimg_x86-19_r01.zip


Intel® GPA: Which Version Should I Download and Install?

$
0
0

Introduction

Initially, Intel GPA was created for developers targeting PC games running on Windows* OS. Many of the top-selling games use Intel GPA when analyzing and optimizing their games running on Windows* OS systems. Now you can also analyze OpenGL* ES workloads with Intel GPA.

You can download various versions of the product from the Intel GPA Home Page. Click the Download button on the page to see a popup dialog box which includes download links for the different platforms. Depending upon the target system your application runs on and the client system you develop on, select one of the following versions:

Intel® GPA Version

Analysis Platform
(your development system)

Target Application and Platform

“Develop for Windows 7*, Windows 8*”

Windows* OS

Microsoft DirectX* applications for Windows* OS

“Develop for Android* on Windows*”

Windows* OS

OpenGL* ES applications for Android*

“Develop for Android* on OS X*”

OS X*

OpenGL* ES applications for Android*

“Develop for Android* on Ubuntu*”

Ubuntu* OS

OpenGL* ES applications for Android*

Details

For Windows* OS workloads, you can run one of the following tools: Intel GPA System Analyzer (both HUD and Remote), Intel GPA Frame Analyzer, and Intel GPA Platform Analyzer. Each of these tools can help you quickly pinpoint performance issues with a different aspect of the graphics application, such as whether the game is CPU-bound or GPU-bound, or what portions of the rendering pipeline are responsible for performance bottlenecks within a specific frame.

For Android* workloads, you can use the following tools:

  • Intel GPA System Analyzer supports game analysis for Android* phones and tablets based on the Intel® Atom™ processor. With this capability, you can get a real-time view of over two dozen critical system metrics covering the CPU, GPU, and OpenGL ES* API. In addition, the tool provides a number of graphics pipeline experiments that can help you quickly isolate graphics bottlenecks.
  • If you are using a tablet based on the Intel® Atom™ processor, you can also run the Intel GPA Frame Analyzer to perform frame-based analysis and optimization of your application.
  • For Android* devices based on Intel® Atom™ processors with PowerVR* Graphics, you can now run Intel GPA Platform Analyzer to perform platform analysis.

Intel GPA Installation Specifics

The Intel GPA architecture is quite adaptable, and is based upon communication via sockets between the target system (where your game runs) and the analysis system (where you run the Intel GPA tools). This extensible architecture enables the product to support the analysis of both Windows* OS platforms as well as mobile platforms -- you can analyze games on Intel® Atom™ phones and tablets running the Android* OS from a variety of development systems: Apple OS X*, Linux* Ubuntu*, and the Windows* OS.

Here is a chart showing the different platforms supported by Intel GPA, and some tips on installation of the product:

Target Platform
(where your game runs)
Analysis Platform
(your development system)
Installation Information
Microsoft* Windows* 7/8/8.1 OSMicrosoft* Windows* 7/8/8.1 OSInstall the software on both the
Target Platform and the Analysis Platform
Google* Android* 2.3, 4.0, 4.1, 4.2, 4.3
(Intel® Atom™ phones/tablets)
OS X* 10.7, 10.8
Microsoft* Windows* 7/8 OS
Ubuntu* OS 11.10, 12.04
Install the software only on the Analysis Platform

A couple of notes regarding the table above:

  • For the Windows* OS target platform, all Intel GPA tools can run on both the target platform and the analysis platform (that is, Intel GPA System Analyzer HUD, Intel GPA System Analyzer (client/server mode), Intel GPA Frame Analyzer, and Intel GPA Platform Analyzer).
  • For the Android* OS target platform, only the Intel GPA System Analyzer runs on the target platform in the client/server mode, with the following exceptions:
    • On tablets based on the Intel processor codenamed Bay Trail, Intel GPA Frame Analyzer can also be used for frame analysis of OpenGL* games and applications.
    • On Android* devices based on Intel Atom processor with PowerVR* Graphics, Intel GPA Platform Analyzer can be used for platform analysis.
  • For the Microsoft* Windows* 8 OS, Intel GPA does not support the RT version of this OS.
  • For more information about Intel GPA on the Android* OS platform, either read this article or see the Android* section of the Intel GPA Online Help.

Shadow Mapping Algorithm for Android*

$
0
0

By Stanislav Pavlov

Downloads


Shadow Mapping Algorithm for Android* [PDF 440KB]

"There is no light without shadows" - Japanese proverb

Because shadows in games make them more realistic and interesting, including well-rendered shadows in your games is important. Currently, most games do not have shadows, but this situation is changing. In this paper we will discuss a common method for realizing shadows, called Shadow Mapping.

Shadow Mapping Theory

Shadow mapping is one of the most conventional techniques for shadow generation in real-time applications. The method is based on the observation that whatever can be seen from the position of the light source is lit; the rest is in the shade. The principle of this method consists in comparing the depth of the current fragment in the reference system associated with the light source to that which is closest to the light source geometry.

The algorithm consists of just two stages:

1. The shadow map generation
2. The rendering stage

The algorithm’s main advantage is that is it easy to understand and implement. Its disadvantages include that it requires more CPU and GPU resources and calculations to make a picture more real. As a result of these additional resources, the shadow map in the depth buffer could become slower.

Algorithm Realization

To create a shadow map, it is necessary to render the scene from the position of the light source. Thus, we obtain the shadow map in the depth buffer, which contains depth values ​​closest to the light source geometry. This approach has the advantage of speed, since the depth buffer generation algorithm is implemented in the hardware.

At the final stage, rendering occurs from the camera position. Each point of the scene is translated into the coordinate system of the light source, and then we calculate the distance from this point to the light source. Calculated distance is compared with the value that is stored in the shadow map. If the distance from the point to the light source is more than the value stored in the shadow map, then this point is in the shadow of any object placed in the path of light.

The code in this article uses the Android SDK (ver. 20) and the Android NDK (ver 8d). It is taken as the basis for a fully native application:  http://developer.android.com/reference/android/app/NativeActivity.html

The Android MegaFon Mint* smartphone is based on the Intel® Atom™ processor Z2460: http://download.intel.com/newsroom/kits/ces/2012/pdfs/AtomprocessorZ2460.pdf

Initialization

The shadow map is stored in a separate texture format GL_DEPTH_COMPONENT, size 512x512 (shadowmapSize.x = shadowmapSize.y = 512), 32 bits per texel (GL_UNSIGNED_INT). In order to optimize, you can use 16 bit textures (GL_UNSIGNED_SHORT). Creating a texture is possible on devices supporting GL_OES_depth_texture [for documentation see http://www.khronos.org/registry/gles/extensions/OES/OES_depth_texture.txt].

The parameters of  GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T are set in GL_CLAMP_TO_EDGE. So when you request any value outside the texture sampling mechanism (sampler), a value corresponding to the boundary is returned. This is done to reduce artifacts from the shadows in the final rendering stage. "Tricks with the fields" will be discussed in another blog.

        //Create the shadow map texture
	glGenTextures(1, &m_textureShadow);
	glBindTexture(GL_TEXTURE_2D, m_textureShadow);
	checkGlError("bind texture");
	// Create the depth texture.
	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowmapSize.x, shadowmapSize.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
	checkGlError("image2d");
	// Set the textures parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	// create frame buffer object for shadow pass
	glGenFramebuffers(1, &m_fboShadow);
	glBindFramebuffer(GL_FRAMEBUFFER, m_fboShadow);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textureShadow, 0);
	checkGlError("shadowmaptexture");
	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if(status != GL_FRAMEBUFFER_COMPLETE) {
		LOGI("init: ");
		LOGI("failed to make complete framebuffer object %xn", status);
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);

The next initialization phase is the preparation of shaders.

Below is the Vertex shader attribute. This is the next step of generating shadow maps:

vec3 Position;

uniform mat4 Projection;
uniform mat4 Modelview;

void main(void)
{
	gl_Position = Projection * Modelview * vec4(Position, 1);
}

Pixel shader (step shadow generation):
highp vec4 Color = vec4(0.2, 0.4, 0.5, 1.0);

void main(void)
{
	gl_FragColor = Color;
}

The main task of shaders is to write the geometry, or in other words, to generate the depth buffer for the main stage.

Stages of shadow map rendering

These steps differ from the usual stages of the vectorization scene by the next few points:

  1. FBO, which acts as our depth buffer, is attached to the texture (shadow map) glBindFramebuffer (GL_FRAMEBUFFER, m_fboShadow).
  2. You can render shadows using orthographic projection from directional sources (the sun), or from a conical (omni) perspective. In the example, the chosen perspective projection matrix lightProjectionMatrix has a wide viewing angle—90 degrees.
  3. The color entry in the frame buffer is from the glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE). This optimization can be very useful if you use a complex pixel shader.
  4. At this stage, the map is drawn only for the rear surface of the polygons, glCullFace (GL_FRONT). This is one of the most effective and easiest methods to reduce the negative effects of artifacts on the shadow map method. (Note: this is not useful for all geometries.)
  5. Area will draw 1 pixel on each side is smaller than the shadow map glViewport ( 0, 0 , shadowmapSize.x - 2 , shadowmapSize.y - 2). This is done in order to leave the "field" on the shadow map.
  6. After drawing all the elements of the scene, we return to its original value glCullFace (GL_BACK), glBindFramebuffer (GL_FRAMEBUFFER, 0) and glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE).
void RenderingEngine2::shadowPass() {
	GLenum status;
	glEnable(GL_DEPTH_TEST);
	glBindFramebuffer(GL_FRAMEBUFFER, m_fboShadow);
	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE) {
		LOGE("Shadow pass: ");
		LOGE("failed to make complete framebuffer object %xn", status);
	}
	glClear(GL_DEPTH_BUFFER_BIT);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

	lightProjectionMatrix = VerticalFieldOfView(90.0,
			(shadowmapSize.x + 0.0) / shadowmapSize.y, 0.1, 100.0);
	lightModelviewMatrix = LookAt(vec3(0, 4, 7), vec3(0.0, 0.0, 0.0), vec3(0, -7, 4));
	glCullFace(GL_FRONT);
	glUseProgram(m_simpleProgram);
	glUniformMatrix4fv(uniformProjectionMain, 1, 0,
			lightProjectionMatrix.Pointer());
	glUniformMatrix4fv(uniformModelviewMain, 1, 0,
			lightModelviewMatrix.Pointer());
	glViewport(0, 0, shadowmapSize.x - 2, shadowmapSize.y - 2);

	GLsizei stride = sizeof(Vertex);
	const vector& objects = m_Scene.getModels();
	const GLvoid* bodyOffset = 0;
	for (int i = 0; i < objects.size(); ++i) {
		lightModelviewMatrix = objects[i].m_Transform * LookAt(vec3(0, 4, 7), vec3(0.0, 0.0, 0.0), vec3(0, -7, 4));
		glUniformMatrix4fv(uniformModelviewMain, 1, 0, lightModelviewMatrix.Pointer());
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objects[i].m_indexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, objects[i].m_vertexBuffer);

		glVertexAttribPointer(attribPositionMain, 3, GL_FLOAT, GL_FALSE, stride,
				(GLvoid*) offsetof(Vertex, Position));

		glEnableVertexAttribArray(attribPositionMain);

		glDrawElements(GL_TRIANGLES, objects[i].m_indexCount, GL_UNSIGNED_SHORT,
				bodyOffset);

		glDisableVertexAttribArray(attribPositionMain);
	}
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glCullFace(GL_BACK);
}

 

Rendering scenes with shadows

The first stage of this specific feature is to set textures with the shadow map obtained in the previous step:

glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_textureShadow);
	glUniform1i(uniformShadowMapTextureShadow, 0);

void RenderingEngine2::mainPass() {
	glClearColor(0.5f, 0.5f, 0.5f, 1);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	modelviewMatrix = scale * rotation * translation
			* LookAt(vec3(0, 8, 7), vec3(0.0, 0.0, 0.0), vec3(0, 7, -8));
	lightModelviewMatrix = LookAt(vec3(0, 4, 7), vec3(0.0, 0.0, 0.0), vec3(0, -7, 4));

	projectionMatrix = VerticalFieldOfView(45.0, (screen.x + 0.0) / screen.y, 0.1, 100.0);
	mat4 offsetLight = mat4::Scale(0.5f) * mat4::Translate(0.5, 0.5, 0.5);
	mat4 lightMatrix = lightModelviewMatrix * lightProjectionMatrix	* offsetLight;
	glUseProgram(m_shadowMapProgram);
	glUniformMatrix4fv(uniformLightMatrixShadow, 1, 0, lightMatrix.Pointer());
	glUniformMatrix4fv(uniformProjectionShadow, 1, 0, projectionMatrix.Pointer());
	glUniformMatrix4fv(uniformModelviewShadow, 1, 0, modelviewMatrix.Pointer());

	glViewport(0, 0, screen.x, screen.y);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_textureShadow);
	glUniform1i(uniformShadowMapTextureShadow, 0);

	GLsizei stride = sizeof(Vertex);
	const vector& objects = m_Scene.getModels();
	const GLvoid* bodyOffset = 0;
	for (int i = 0; i < objects.size(); ++i) {
		modelviewMatrix = scale * rotation * translation * LookAt(vec3(0, 8, 7), vec3(0.0, 0.0, 0.0), vec3(0, 7, -8));
		glUniformMatrix4fv(uniformTransformShadow, 1, 0, objects[i].m_Transform.Pointer());
		glUniformMatrix4fv(uniformModelviewShadow, 1, 0, modelviewMatrix.Pointer());
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objects[i].m_indexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, objects[i].m_vertexBuffer);

		glVertexAttribPointer(attribPositionShadow, 3, GL_FLOAT, GL_FALSE,
				stride, (GLvoid*) offsetof(Vertex, Position));
		glVertexAttribPointer(attribColorShadow, 4, GL_FLOAT, GL_FALSE, stride,
				(GLvoid*) offsetof(Vertex, Color));
		glVertexAttribPointer(attribNormalShadow, 3, GL_FLOAT, GL_FALSE, stride,
				(GLvoid*) offsetof(Vertex, Normal));
		glVertexAttribPointer(attribTexCoordShadow, 2, GL_FLOAT, GL_FALSE,
				stride, (GLvoid*) offsetof(Vertex, TexCoord));

		glEnableVertexAttribArray(attribPositionShadow);
		glEnableVertexAttribArray(attribNormalShadow);
		glEnableVertexAttribArray(attribColorShadow);
		glEnableVertexAttribArray(attribTexCoordShadow);

		glDrawElements(GL_TRIANGLES, objects[i].m_indexCount, GL_UNSIGNED_SHORT,
				bodyOffset);

		glDisableVertexAttribArray(attribColorShadow);
		glDisableVertexAttribArray(attribPositionShadow);
		glDisableVertexAttribArray(attribNormalShadow);
		glDisableVertexAttribArray(attribTexCoordShadow);
	}
}

The most interesting parts of these rendering shadows are the shaders. Here’s the technique.

Vertex shader (draws shadows):

attribute vec3 Position;
attribute vec3 Normal;
attribute vec4 SourceColor;
attribute vec2 TexCoord;

varying vec4 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
varying vec4 fShadowMapCoord;

uniform mat4 Projection;
uniform mat4 Modelview;
uniform mat4 lightMatrix;
uniform mat4 Transform;

void main(void)
{
	fColor = SourceColor;
	gl_Position = Projection * Modelview * Transform * vec4(Position, 1.0);
	fShadowMapCoord = lightMatrix * Transform * vec4(Position, 1.0);
	fNormal = normalize(Normal);
	fTexCoord = TexCoord;
}

The vertex shader, in parallel with its usual work, produces a translation of vertices in the plane of the light source. In this example, the transition to the plane of the light given by the matrix lightMatrix and the result are passed to the pixel shader through fShadowMapCoord.

Pixel shader (draws shadows):

uniform highp sampler2D shadowMapTex;

varying lowp vec4 fColor;
varying lowp vec3 fNormal;
varying highp vec2 fTexCoord;
varying highp vec4 fShadowMapCoord;

highp vec3 Light = vec3(0.0, 4.0, 7.0);
highp vec4 Color = vec4(0.2, 0.4, 0.5, 1.0);

void main(void)
{
	const lowp float fAmbient = 0.4;
	Light = normalize(Light);
	highp float depth = (fShadowMapCoord.z / fShadowMapCoord.w);
	highp float depth_light = texture2DProj(shadowMapTex, fShadowMapCoord).r;
	highp float visibility = depth <= depth_light ? 1.0 : 0.2;
	gl_FragColor = fColor * max(0.0, dot(fNormal, Light)) * visibility;
}

The pixel shader calculates each pixel value depth based on the relative light source and compares it with the value corresponding to it in the depth map. If the value does not exceed the depth of the depth maps, it is visible from the source position; otherwise, it is in the shade. In this example, we change the visual color intensity using the coefficient visibility, but in general, it is a more difficult technique.

About the Authors

Stanislav works in the Software & Service Group at Intel Corporation. He has 10+ years of experience in software development. His main interest is optimization of performance, power consumption, and parallel programming. In his current role as an Application Engineer providing technical support for Intel® processor-based devices, Stanislav works closely with software developers and SoC architects to help them achieve the best possible performance on Intel platforms. Stanislav holds a Master's degree in Mathematical Economics from the National Research University Higher School of Economics.

Iliya, co-author of this blog, is also a Senior Software Engineer in the Software & Service Group at Intel. He is a developer on the Intel® VTune™ Amplifier team. He received a Master’s degree from the Nizhniy Novgorod State Technical University.

Using the Beacon Mountain Toolset and NDK for Native App Development

$
0
0


Download as PDF

Download Source Code

Summary: The goal of this project is to demonstrate how easy it is to build native Android apps with the Beacon Mountain toolset and Intel NDK.  We will do this by building a simple game. We will walk through the steps of installing tools with Beacon Mountain, building the game, and testing it with the Intel® Hardware Accelerated Execution Manager (Intel® HAXM) emulator. Commented source code is also available.

Installing Beacon Mountain

Beacon Mountain is a one-click install for most of the tools needed for developing Android* applications, including Eclipse* and the Android SDK and NDK. This can save hours or even days of downloading, building, and installing different packages and development tools.

Install Beacon Mountain from here: http://software.intel.com/en-us/vcsource/tools/beaconmountain

Creating the project

  1. Open Eclipse ADT and create a new workspace called MazeGame.



    Click the New Android Application button and set the project name to MazeGame. Change all API levels to API 17: Android 4.2.



    Click Next, accepting all default settings, until the Finish button appears, then click it.
     
  2. Since we are creating an app that will involve native C++ code, we need to set the NDK location. Click Window->Preferences and expand the Android menu. Browse to the location of your Beacon Mountain install folder, select the NDK folder inside it, and click OK.


     
  3. To enable native C++ compilation, right-click the project, and select Android Tools->Add Native Support.



    Accept the default library name by clicking Finish.
     
  4. By default, our project will only build for ARM devices. To enable building for x86 devices, we'll need to create an Application.mk file alongside our Android.mk in the /jni folder and add the following.
APP_ABI := x86 armeabi
APP_STL := stlport_static

After building, you should see armeabie and x86 folders inside MazeGame/MazeGame/bin.

Game Structure

Although there are many good ways to structure our game, we'll start with the simplest possible format:

  • A nearly empty activity that loads a view.
  • A view that extends GLSurfaceView. We'll call into our native code from here to render each frame.
  • A C++ MazeGame class that will manage all the game objects, the physics engine, communication with the Java* wrapper and OpenGL* setup.
  • A C++ GameObject class that will manage object position, 3D model parsing, and drawing itself.

Calling Native C++ Code From Java

To call native code, we'll need to load our library (the one we configured when we created the Project) at the end of our view file.

static {
        System.loadLibrary("MazeGame");
    }

Note that the actual library (inside the lib/x86 folder) will be called libMazeGame.so, not MazeGame.so.

We'll also need to define Java versions of the native functions we'll be calling:

    public native void init(int rotationDegrees);
    public native void restart();
    public native void setRotation(int degrees);
    public native void loadResources(Bitmap circuitBoardBitmap, Bitmap componentsBitmap, Bitmap stripesBitmap, Bitmap ballBitmap);
    public native void resize(int width, int height);
    public native void renderFrame(double timeStepSeconds, double currTimeSeconds);
    public native void accelerometerChanged(float x, float y);
    public native void deinit();

Finally, we'll need to define these functions in MazeGame.cpp. Native code functions require a very unique format to be externally callable:

JNIEXPORT void JNICALL Java_com_example_mazegame_MazeGameView_init(JNIEnv* env, jobject thisClazz, int rotationDegrees){
gameInst = new MazeGame(env, thisClazz, rotationDegrees);
gameInst->restart();
}

Notice the function name. It starts with the full classpath of the Java file that will be calling into it. Also, the first two arguments are passed in by the system, so they are required, and there are no matching parameters for them on the Java side.

Because this is C++ and not C, we'll need to add EXTERN C linkage for them above the function definitions.

extern "C" {
JNIEXPORT void JNICALL Java_com_example_mazegame_MazeGameView_init(JNIEnv* env, jobject obj, int rotationDegrees);

Calling Java From C++

Some tasks, like playing sounds and opening dialogs, are best done in Java, so we'll need a way to call back out from our native C++ code. In our constructor, we'll save references to the calling class and the PlaySound method on that class:

MazeGame::MazeGame(JNIEnv* env, jobject clazz, int rotationDegrees)
{
_environment = env;
_callingClass = (jclass)(env->NewGlobalRef(clazz));
jclass viewClass = env->FindClass("com/example/mazegame/MazeGameView");
_playSoundMethodID = env->GetMethodID(viewClass, "PlaySound", "(Ljava/lang/String;)V");
_showGameOverDialogMethodID = env->GetMethodID(viewClass, "ShowGameOverDialog", "()V");

Then, when we are ready to play a sound, we can simply call the saved reference:

void MazeGame::playSound(const char* soundId){
jstring jstr = _environment->NewStringUTF(soundId);
    _environment->CallVoidMethod(_callingClass, _playSoundMethodID, jstr);
}

Integrating Box2D

One of the best things about the NDK is that it allows development teams to use existing C++ libraries, such as the well-known Box2D physics engine. After downloading and unzipping Box2D, move it into the jni folder. We'll also need to link in all of the Box2D libraries in our jni/Android.mk file:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := maze-game
FILE_LIST := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/Box2D/Collision/*.cpp) $(wildcard $(LOCAL_PATH)/Box2D/Collision/Shapes/*.cpp) $(wildcard $(LOCAL_PATH)/Box2D/Common/*.cpp) $(wildcard $(LOCAL_PATH)/Box2D/Dynamics/*.cpp) $(wildcard $(LOCAL_PATH)/Box2D/Dynamics/Contacts/*.cpp) $(wildcard $(LOCAL_PATH)/Box2D/Dynamics/Joints/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)

Now we can include Box2D in our code:

#include 
...
b2World* _world;

Testing with the Intel HAXM Emulator

The Intel HAXM emulator, part of the Beacon Mountain toolset, provides a massive speed increase over the stock Android emulators. This can be crucial for game development, as testing many scenarios becomes impossible at low frame rates.

Begin by right-clicking the project and choosing Properties. Click the Run/Debug Settings item in the left-nav. To test our project, we'll need to add a launch configuration. So click the New button and select Android Application from the list.

Under the Android tab, click Browse and select the main project. Then click the Target tab and select the x86 device from the list.

Click OK. We can now test our project by right-clicking it and selecting Run As->Android Application.

Summary

This has been a high-level overview of how the Beacon Mountain toolset can accelerate Android game development. For more information, download the full source code of the sample application or check out the Beacon Mountain home page (http://software.intel.com/en-us/vcsource/tools/beaconmountain).

Android 应用程序开发另解及 Android SDK 工具集的另类用法

$
0
0

相信对于广大Android应用开发爱好者来说,Android SDK工具集的大家都已经能够很熟练的使用,但是我这里要介绍的是SDK工具集的非常用使用方法,即“另类用法”。

首先要说的是,大部分的Android应用程序开发者是基于Android模拟器来开发应用程序的,这种开发方式虽然很方便,直接用Eclipse就可以集成开发环境,基本上不需要手动去设置或者操作什么,但是同时也有几点很大的弊端:

1、Android模拟器的内存有限,如果开发相对比较耗资源的应用程序,就比较头疼了--模拟器运行的十分缓慢;而且随着模拟器分辨率设置的变化,分辨率越大模拟器就越卡也给应用开发带来了不小的困扰。这时候有些通报可能就会选择购买开发板或者用买个Android手机来进行应用的开发。但是其实,我们是有更好的方式来做Android的应用开发,这里先卖个关子。

2、通常来说,大家进行Android应用程序的开发都是在本机上实现的,也就是说代码编辑和模拟器运行是在同一台机器上实现的,但是有没有想过将这两者分别在两个机器上进行,或者说用虚拟机来实现Android系统的模拟呢?

说到这里,大家是不是觉得很有意思呢?

 

其实,Android不止是提供了arm版的!!!这里要隆重介绍一下Android—x86版,有不了解的朋友可以百度一下。

其实说起来很简单,使用android-x86进行应用程序的开发需要经历一下几个步骤:

1、找一台linux主机或者装一个虚拟机

2、下载android-x86源代码并进行编译(这部分本人就不再这里详细介绍了,百度一下大把大把的)

3、将编译生成的android镜像(一般名为generic-x86.iso)用虚拟机运行

经过一下几步,大家就可以看到一个类似操作系统的android系统了,它的好处是,你可以随意设置这个系统的内存大小,flash大小,CPU频率等各种硬件属性,使得你的应用程序开发不需要再考虑各种硬件资源对模拟器的影响,你不用再喝着咖啡吃着面包看着模拟器缓慢的运行心里干着急了!!!甚至,你完全可以找一台主机,把android系统装到台式机或者笔记本上!!

 

写到这里,关键的问题就来了,可能有些朋友就要问了,这样的话,要怎么样把应用程序开发与android-x86这个系统联系起来呢?

这就涉及到本文的第二部分了,即android sdk工具集的另类用法。

 

首先说一种比较傻瓜式的方式:你可以将编译成的android apk应用程序通过U盘挂载到andriod-x86系统上,然后通过U盘对应用进行安装。不过显然,如果只能用这种方式的话,我也不会写这篇文章里。

其实android sdk工具集本身已经做得够强大了,只要大家细心看看sdk各工具的使用说明就能发现,这里鄙人做下简单的说明:

adb工具的使用其实并不只局限于对模拟器的使用,它还有更强大的用法。

adb connect使用说明:

按照刚才说的,你已经将android-x86通过虚拟机运行起来了,或者你资源比较丰富,一不做二不休已经将这个系统装到另外一个系统上来,那么接下来,就说一下实现的详细步骤。

首先,在虚拟机或者装有android系统的主机上用ALT+F1,你会惊奇的发现,原来这个系统还有提供命令行界面!其实想想这也没什么好奇怪的,因为android使用的是linux内核,而linux内核的ALT+F1就是切入命令行界面的快捷键,同样的,要重新回到图形界面,ALT+F7就行了,这和linux系统也是一致的。

进入命令行界面之后,敲入netcfg命令,我们可以看到这个系统的ip,比如说这里我们看到的是192.168.1.160。

接下来,就是adb工具的另类用法了:adb connect 192.168.1.160:5555(冒号前面的参数是你android-x86系统的ip,后面那个参数是端口号,不可变)。

当显示连接成功的时候,所有的猪呢比工作都已经准备完成了。

接下来,就是见证奇迹的时刻:

在windows主机下使用adb install命令将你主机上有的apk应用程序安装一下,你就会惊喜的发现,这个应用程序居然被安装到了android-x86系统上,并且运行的飞快,比那什么什么模拟器快了不知道多少倍!!!

更有甚者,你会发现,怎么你通过Eclipse运行应用程序之后,模拟器并没有打开,而这个应用程序已经神奇的运行到了android-x86系统上来!!!

这是怎么回事呢?

其实原理很简单,之所以起初你使用adb install和用Eclipse运行程序的时候程序会装到模拟器上,是因为adb这时候模拟连接的就是模拟器,而当你使用adb connect连接上了android-x86系统上的时候,这个“默认的模拟器”就变成了你的虚拟机或者另外一个anddroid主机了,这样一来,所以对“模拟器”的操作都将会在android-x86系统上执行。

是不是很神奇呢?

如果有兴趣的话,不妨一试哦!虽然可能起初会花费你一些时间,但是带来的快乐和之后开发的高效,一定会给你意想不到的收获的!!

Migrate Android* Phone Apps to Tablets

$
0
0

Introduction

One of the problems that has occurred over the last few years of rapid mobile device proliferation is because smartphones came out before tablets, developers designed applications for smartphones first. When tablets came out with similar operating systems but different screen sizes, developers had a new market for their software; however, most did not change their approach to user interaction. The Android* OS is capable of adjusting most smartphone applications to tablet-sized screens, but usually the app doesn’t look right and doesn’t provide the experience users expect from a tablet application.

When developers build applications for tablets, they need to redesign and redeploy the application for tablets to match with visual and user experience expectations. In this article, we give advice and perspective to developers who want to migrate their Android smartphone application to Android tablet.

How to Begin

First, we need to come up with a methodology to make the migration as efficient as possible, without spending too much time and resources.

To do this, we will walk through the hardware and software differences between smartphones and tablets as well as user experience scenarios for both of the devices.

The diagram below shows the steps to follow:

Device Analysis: Tablets vs Smartphones

HW Differences

The most obvious hardware difference between smartphones and tablets is the screen size. Devices with screens larger than 7-inches are considered tablets, and smartphones have smaller screen sizes like 3.5”, 2.5”, 4.2”, etc. Tablets’ larger screen size creates different resolutions, user experience, and human-computer interaction that developers need to be aware of.



(Motorola Razr-i* Smartphone with 4.3” screen size, Asus Fonepad* with 7” screen size, and Android* tablet with 10.1” screen size, respectively.)

People tend to use tablets with their larger screen sizes for tasks that are more intensive and where they tend to spend more time within an application, like more lengthy reading, more interaction with games, and watching movies. Phones are smaller, hence more mobile to carry around and convenient for getting quick information. Smartphone applications are designed to navigate application features quickly and supply small chunks of information on smaller screens.

Device size affects how people hold the device, how many fingers they use at the same time, or in what situation they use the device, like standing, sitting, walking, etc. These differences determine the human-computer interaction.

In addition to the user experience issues, screen resolutions change between devices so developers should consider screen resolution differences and how they affect user habits when migrating smartphone applications to tablets.

Another hardware difference to account for is that most tablets do not have cellular network connection like smartphones do. So application developers should assume the absence of cellular network when designing their tablet applications.

SW Differences

The Android OS was originally designed and developed for smartphones. Then Google created v3.0, a.k.a Honeycomb*, for tablets. But since Android v4.0, a.k.a Ice Cream Sandwich*, the same OS is used on smartphones and tablets, and the releases following v4.0 have been released for both. The pictures below show a phone and tablet with the Ice Cream Sandwich home screen. They show the basic interface differences users encounter on the two devices.



(Android* Ice Cream Sandwich* 4.3” Phone and 10.1” Tablet Home Screen)

The main differences between the home screens are:

  • The notification area is above the screen on smartphones, while it is mostly in the right bottom corner on tablets (changes according to tablet screen size or the manufacturer’s UI design)
  • The Applications menu icon is at the bottom center of the smartphone screen, while it is mostly in the top right corner of the tablet.
  • The Quick navigation buttons are at the bottom of the screen on smartphones, but they are in the bottom left corner of the screen on tablets.

If your Android smartphone application was developed for Android v4.0 or later versions, the software stack is the same for tablets but if your smartphone application was developed for an earlier version, even though Android* is backward compatible, you should visit the SDK version history to see the changes, detect the deprecated methods, implement, and rebuild the code.

User Experience: Human-Computer Interaction with Tablets

As it has been mentioned in the hardware differences section, people use phones and tablets differently. People usually carry smartphones around with them, so they tend to use them for communication (calls, messaging, tweeting, etc.) and for short reading instead of concentrated actions like reading books, articles, etc., writing long emails, and other entertainment or productivity applications. It is common to show short information on the small phone screen. But when you move your app to tablets, you can show more information on the screen, and users tend to dwell longer while looking at the screen instead of a quick scan of information.

It is also more common to use tablets instead of smartphones for production tasks, including writing longer notes, photo and video editing, creating presentations, writing long emails, etc. These uses mean that people tend to use tablets in more static situations instead of mobile conditions since tablets are larger, have larger screens to enjoy and larger soft keyboard to make typing easier, and so on.

Tablets are designed to be rotated more than phones as both landscape and portrait mode are large enough on a tablet to legibly show text and graphics in either mode. Designing the application user interface on a tablet to optimize for both landscape and portrait states of the screen is important as the application can present an enhanced user experience when compared with a smartphone. One suggestion is to give more data space to an application window so users can more easily enter text or follow the state of the application.

Design Decisions

After analyzing the hardware, software, and user interaction differences between tablets and smartphones, it is easier to see what the design decisions are for tablet applications. Here’s a list of the most common actions that need to be considered:

  • Redesigning the user interface to account for how people use the application on a tablet.
  • Adding more visuals and text on the screen.
  • Recreating of some visual content for the user interface due to differences in screen resolution. To fill the larger screen, the OS would have to stretch some visual resources, distorting them. It’s likely going to be better to replace an image that would be stretched with a higher definition one.

Android UI Development

In most cases Android adjusts your application layout to fit the current device screen. In some cases it works fine, but in other cases the UI might not look as good and might need some adjustments. Even if you designed a dynamic UI, scaling images and widgets might not be so user friendly. Since the XML files were designed for smartphones, you need to create new XML files and design for tablet-sized devices.

Here we have some quick tips for designing the user interface for tablets.

  • Use new high-res image resources instead of low-res ones to improve the quality of user interface. Otherwise, your app images will be pixellated and your application will look bad. Rescaling the low-res images;

  • Letting the OS stretch the user interface widgets could look worse than you think. Try to centralize the user interface elements. Below is a sample user interface for a phone app that was stretched to fit on a tablet.;



    (TextField Widget on phone being adjusted to show on a tablet)

  • Using absolute layouts is hard to manage since you need to specify exact locations of the user interface elements, making it hard for your application to accommodate different screen sizes and adjust for landscape and portrait modes. It is advised to use linear or relative layouts.

Developing the new User Interface

The Android SDK allows developers to create multiple UIs with XML files for different sizes of screens. The system handles most of the work to render your application properly on each screen configuration by scaling layouts to fit the screen size and density with scaling bitmap drawables for the screen density as appropriate.

In the Android project you can use these folders to ensure your app uses appropriate screen design.

res/layout/my_layout.xml“regular screen size”

res/layout-large/my_layout.xml “larger screen size”

Or declare the specific resolution screen with:

res/layout-sw600dp/main_activity.xml For 7” tablets (600dp wide and bigger)

res/layout-sw720dp/main_activity.xml For 10” tablets (720dp wide and bigger)



(Android Project Folder Structure shows resource folders for different resolutions)

Using Fragments

The Android SDK provides fragments for creating more dynamic user interfaces. Using fragments, developers can include more functionality on a tablet application screen, giving users more benefits. Developers can create sub-activities for different parts of the screen by defining a fragment for each sub-activity in an Android activity class.



(Fragments Visualization on devices)

Fragments have their own lifecycle similar to an activity with stack, state, and back-stack.

When an activity creates a fragment, it is attached to the activity, so the developer can define what the attached fragment does.

public void onAttach(Activity activity){  	
	super.onAttach(activity); 
	}

Multiple fragments can be attached and detached to an activity so developers can add more functionality to one screen by managing the fragments. Fragment APIs provide the FragmentManager class to manage fragment objects within an activity.

Using Fragments, you don’t have to start a new activity and switch to a brand new window. The user can stay on the same screen and continue to interact with the same UI. Using the same screen fragments can mean that your app runs faster also.



(Fragments Lifecycle)

Fragments also have subclasses like DialogFragment, ListFragment, PreferenceFragment that are similar to activity correspondence, e.g., ListActivity. By using the appropriate subclass, you can design more dynamic applications.

The Android SDK comes with sample fragment applications for both phones and tablets. The screenshots below are from a sample that uses list fragments to dynamically change the reading pane without changing the window and starting a new activity.



(ListFragment on tablet)



(ListFragment on Phone)

Android Tablet Application Deployment

When declaring the support for multiple screens for your application, you need to edit your application’s AndroidManifest.xml file and add the <supported-screen> tag. The tag supports `android:requiresSmallestWithDp, android:compatibleWidthLimitDp, androidLargestWidthLimitDp`. Your manifest file will then look something like this:

<manifest ... >
  <supports-screens 	android:requiresSmallestWidthDp="600" />
    ...
</manifest>

Resources

Conclusion

Migrating your application from smartphone to tablet is suggested to present best user experience to users and take more attention than an adjusted smartphone application on tablet. As mentioned in the article Android* SDK is helpful to make your work easier during migration and redesign of your application if you decide the new tablet design of your application.

Other Related Articles

  1. “User Experience Design Guidelines for Tablets running Android*” article helps you to build a User Interface that looks great and accomplishes your goals.

    http://software.intel.com/en-us/articles/user-experience-design-guidelines-for-tablets-running-android
  2. “Designing for User Experience, Power, and Performance on Tablets” article helps you by giving issues to consider when working out your User Interface and overall user experience.

    http://software.intel.com/en-us/articles/designing-for-user-experience-power-and-performance-on-tablets
  3. “Intel for Android* Developers Learning Series #4: Android Tablet Sensors” article provides you a sensor based application development on Android tablets, it is a good read to review application development process on Android tablets.

    http://software.intel.com/en-us/articles/intel-for-android-developers-learning-series-4-android-tablet-sensors
  4. “Mobile OS Architecture Trends” article gives an overview of mobile OS design and architecture such as user experience, power management, security design, cloud support and openness design.

    http://software.intel.com/en-us/articles/mobile-os-architecture-trends

About Author

Onur is working as Software Engineer for Intel® Corporation more than 3 years. He has worked on Android* and Linux* systems with various Intel platforms and technologies. He is currently working in Intel Labs Istanbul as Software Development Engineer.

Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.

Copyright © 2014 Intel Corporation. All rights reserved.

*Other names and brands may be claimed as the property of others.

Creazione e porting di applicazioni Android* basate su NDK per l'architettura Intel

$
0
0

Obiettivo

Quest'articolo è un'introduzione per principianti sulla creazione di applicazioni native Android* (basate su NDK) per i dispositivi basati sull'architettura Intel®. Tratta anche del porting verso i dispositivi basati sull'architettura Intel di applicazioni NDK Android originariamente create per dispositivi basati su altre architetture. Analizzeremo due scenari, uno per mostrare il processo completo di creazione di una semplice applicazione Android* basata su NDK e l'altro per dimostrare un semplice processo di porting di un'applicazione Android basata su NDK affinché sia utilizzabile su dispositivi basati sull'architettura Intel.

Indice

1. Introduzione

2. Creazione di un'applicazione Android basata su NDK per dispositivi basati sull'architettura Intel - Procedura dettagliata di una semplice applicazione

a. Creare un progetto Android predefinito
b. Richiamare il codice nativo dai file sorgente Java
c. Usare javah per generare gli stub dell'header JNI per il codice nativo
d. Compilare il codice nativo con l'NDK per l'architettura Intel
e. Ricompilare, installare ed eseguire l'applicazione Android NDK per l'architettura Intel

3. Uso degli strumenti dell'NDK x86 per eseguire il porting verso dispositivi basati sull'architettura Intel di applicazioni NDK esistenti

4. Riepilogo

Introduzione

È possibile incorporare codice nativo nelle applicazioni Android usando gli strumenti del Native Development Kit (NDK). Questo permette agli sviluppatori di riusare il codice legacy, codificare per l'hardware di basso livello o differenziare le applicazioni sfruttando funzioni che altrimenti non sarebbero ottimali o disponibili.

Questo articolo è un'introduzione elementare su come creare, dall'inizio alla fine, applicazioni basate su NDK per l'architettura Intel e include anche dei semplici casi di utilizzo per eseguire il porting di applicazioni esistenti basate su NDK verso dispositivi basati sull'architettura Intel. Sarà descritto dettagliatamente un semplice scenario di sviluppo di un'applicazione per dimostrare il processo.

Si presume che l'ambiente di sviluppo Android sia già installato, compresi l'Android SDK, l'Android NDK e l'emulatore x86 configurato per testare le applicazioni. Per ulteriori informazioni, si prega di fare riferimento alla sezione della comunità Android nel sito Web di Intel. Per mantenere un ambiente di sviluppo semplice, nella maggior parte dei casi si useranno strumenti della riga di comando Linux*.

Creazione di un'applicazione Android basata su NDK per dispositivi basati sull'architettura Intel - Procedura dettagliata di una semplice applicazione

Si presuma di avere del codice legacy che usa C e il linguaggio assembly per analizzare l'istruzione CPUID (per maggiori informazioni su CPUID, consultare http://en.wikipedia.org/wiki/CPUID*). Qui di seguito è il listato del file sorgente del nostro codice C “legacy” di esempio cpuid.c (che è solo a scopo dimostrativo).

Desideriamo richiamare cpuid_parse dalla nostra applicazione Android (solo a scopo dimostrativo; la funzione cpuid_parse prevede un buffer preallocato) e visualizzare l'output all'interno dell'applicazione.

Qui di seguito è descritta la procedura dettagliata per creare l'applicazione Android dall'inizio alla fine e usare il codice nativo legacy visto in precedenza.

1. Creare un progetto Android predefinito

Android SDK ha strumenti della riga di comando che consentono di generare una struttura di progetto predefinita per un'applicazione hello world tipica. Creeremo innanzitutto un progetto predefinito, quindi modificheremo i file sorgente Java in modo da poter aggiungere chiamate JNI e codice nativo.

Nella schermata precedente, abbiamo prima creato una directory chiamata labs/lab2 e usato lo strumento della riga di comando “android” per generare il progetto predefinito. Abbiamo specificato android-15 come livello di API e chiamato la nostra applicazione “CPUIdApp” con package com.example.cpuid.

Abbiamo quindi usato lo strumento della riga di comando “ant” per creare il progetto in modalità di debug e installare usando “adb” (o reinstallare se già esistente nell'emulatore e nella destinazione). Si presume che abbiate già un emulatore o un dispositivo collegato e che sia l'unico dispositivo che viene elencato nell'output del comando “adb devices”.

La schermata seguente mostra l'emulatore Android x86 con ICS dopo avere completato il processo precedente.

Facendo clic sull'applicazione, viene visualizzato l'output predefinito hello world dell'applicazione. Modificheremo ora l'applicazione per l'uso del codice nativo.

2. Richiamare il codice nativo dai file sorgente Java

Il progetto Android predefinito genera i file sorgente Java per un progetto hello world tipico con lo spazio dei nomi del pacchetto dato (es. com.example.cpuid). La schermata seguente mostra il codice sorgente generato per il file sorgente Java principale.

Per usare il codice nativo C/C++ nel nostro file sorgente Java, dobbiamo prima dichiarare la chiamata JNI e caricare la libreria nativa, come evidenziato nel riquadro giallo della schermata seguente.

Come mostra la dichiarazione, la chiamata nativa restituisce una stringa Java che possiamo usare ovunque nel nostro file sorgente Java. Come illustrato nella schermata precedente, abbiamo modificato TextView in modo che visualizzi la stringa ottenuta dalla chiamata nativa. Questa operazione è evidenziata nel riquadro rosso.

Questo è un caso molto semplice per dichiarare e usare le chiamate JNI native nei file sorgente Java delle applicazioni Android. Useremo quindi lo strumento “javah” per generare gli stub dell'header JNI per il codice nativo e aggiungere o modificare il codice nativo in modo che sia conforme con le header JNI native.

3. Usare “javah” per generare gli stub dell'header JNI per il codice nativo

Dobbiamo ora modificare il nostro codice nativo in modo che sia conforme alla specifica della chiamata JNI. Anche “javah” ci aiuta a generare automaticamente gli stub appropriati dell'header JNI in base ai file sorgente Java. Per generare le header lo strumento “javah” richiede file di classe Java compilati. Usiamo così lo strumento “ant” per generare rapidamente file di classe Java, come mostrato nella schermata sottostante (“ant debug”).

Usare “javah” per generare l'header jni come mostrato nella schermata (secondo riquadro giallo). Questa operazione creerà la directory “jni” e lo stub dell'header in base alla classe Java. La schermata seguente mostra lo stub dell'header nativa JNI generato.

Creare il corrispondente file sorgente C (“com_example_cpuid_CPUIdApp.c”) per l'header precedentemente generata. Qui di seguito è mostrato il listato del file sorgente:

Chiamiamo il codice nativo cpuid_parse e restituiamo il buffer analizzato come stringa JNI. Siamo ora pronti a compilare il codice nativo usando gli strumenti dell'NDK x86.

4. Compilare il codice nativo con l'NDK per x86

Per ulteriori informazioni sull'installazione e l'utilizzo dell'NDK per l'architettura Intel, si prega di fare riferimento alla sezione della comunità Android (/it-it/articles/ndk-for-ia) nel sito Web di Intel.

Gli strumenti dell'Android NDK usano un sistema di compilazione che, per compilare il codice nativo, richiede che nella cartella “jni” del progetto sia presente uno specifico file make Android personalizzato, “Android.mk”. Android.mk specifica tutti i file sorgente C/C++ nativi che devono essere compilati, le header e il tipo di compilazione (es. shared_library).

Qui di seguito è mostrato il listato make Android del nostro progetto (“jni/Android.mk”)

Questo è un semplice scenario con due file sorgente C in cui si specifica di compilare una libreria condivisa.

Possiamo ora inviare l'istruzione “ndk-build APP_ABI=x86” per compilare il codice nativo e generare la libreria condivisa. Il sistema di compilazione Android offre un file make supplementare, “Application.mk”, che possiamo usare per specificare ulteriori opzioni di configurazione. Se ad esempio specifichiamo nel file Application.mk tutte le architetture ABI supportate, ndk-build genererà le librerie condivise native destinate a tutte le architetture.

La schermata precedente mostra la compilazione riuscita del codice nativo per x86 e mostra anche la libreria condivisa che viene generata e installata. Siamo ora pronti a ricompilare la nostra applicazione Android da installare/eseguire sull'emulatore x86 o sul dispositivo di destinazione.

5. Ricompilare, installare ed eseguire l'applicazione Android NDK per l'architettura Intel

Possiamo usare “ant debug clean” per rimuovere i vecchi file di compilazione e inviare di nuovo il comando “ant debug” per avviare la compilazione completa del progetto Android. Usare “adb” per reinstallare l'applicazione sul dispositivo di destinazione o nell'emulatore x86, come mostrato nella schermata seguente.

La schermata seguente mostra l'icona dell'applicazione dentro l'emulatore x86 e il risultato dell'esecuzione dell'applicazione nell'emulatore x86.

Abbiamo creato correttamente, dall'inizio alla fine, un'applicazione Android basata su NDK.

Uso degli strumenti dell'NDK x86 per eseguire il porting verso dispositivi basati sull'architettura Intel di applicazioni NDK esistenti

Le applicazioni Android con codice nativo hanno in genere una struttura di progetto standard, con la cartella “jni” che contiene i file sorgente nativi e i corrispondenti file di compilazione Android.mk/Application.mk. Nella sezione precedente abbiamo visto un semplice esempio con codice sorgente nativo e il corrispondente file Android.mk.

Gli strumenti dell'Android NDK ci permettono di specificare in una volta sola tutte le architetture ABI di destinazione nel file Application.mk e generare automaticamente le librerie condivise native per tutte le destinazioni. Il sistema di compilazione Android inserirà automaticamente tutte le librerie native di destinazione all'interno del pacchetto APK e, al momento dell'installazione, il gestore dei pacchetti Android installerà solo la libreria nativa appropriata per l'architettura di destinazione.

Si può richiamare “ndk-build” oppure nel file Application.mk specificare

APP_ABI := all

OPPURE

APP_ABI := armeabi armeabi-v7a x86

Per ulteriori informazioni, fare riferimento a http://developer.android.com/sdk/ndk/index.html.

Per quanto riguarda il porting di un'applicazione Android esistente con codice nativo e che attualmente non è destinata all'architettura x86, il processo per modificare l'applicazione affinché supporti l'architettura Intel è semplice nella maggior parte dei casi (come descritto in precedenza), a meno che l'applicazione non usi costrutti o un linguaggio assembly specifici dell'architettura. Potrebbero anche incidere altri fattori, come l'allineamento della memoria o l'utilizzo di istruzioni specifiche della piattaforma. Per maggiori informazioni, fare riferimento a /it-it/articles/ndk-android-application-porting-methodologies.

Riepilogo

Questo articolo tratta della creazione e del porting di applicazioni Android basate su NDK per destinarle all'architettura Intel. Con una descrizione dettagliata della procedura abbiamo dimostrato il processo per creare dall'inizio alla fine un'applicazione basata sull'NDK che usi l'architettura Intel. Abbiamo anche descritto un semplice processo, reso disponibile dagli strumenti dell'NDK, per eseguire il porting di applicazioni Android basate su NDK esistenti per destinarle all'architettura Intel.

Avvisi

Intel è un marchio di Intel Corporation registrato negli Stati Uniti e in altri paesi

LE INFORMAZIONI CONTENUTE IN QUESTO DOCUMENTO SONO FORNITE IN ABBINAMENTO AI PRODOTTI INTEL. QUESTO DOCUMENTO NON CONCEDE ALCUNA LICENZA, IMPLICITA O ESPLICITA, MEDIANTE PRECLUSIONE O ALTRO, PER QUANTO RIGUARDA I DIRITTI DI PROPRIETÀ INTELLETTUALE. AD ECCEZIONE DI QUANTO STABILITO DAI TERMINI E DALLE CONDIZIONI DI VENDITA INTEL PER I PRODOTTI IN QUESTIONE, INTEL NON SI ASSUME ALCUNA RESPONSABILITÀ E DISCONOSCE QUALSIASI GARANZIA ESPRESSA O IMPLICITA RELATIVA ALLA VENDITA E/O ALL'UTILIZZO DI PRODOTTI INTEL, INCLUSA LA RESPONSABILITÀ O L'IDONEITÀ AD UNO SCOPO PARTICOLARE, LA COMMERCIABILITÀ O LA VIOLAZIONE DI BREVETTI, COPYRIGHT O ALTRI DIRITTI DI PROPRIETÀ INTELLETTUALE.

Una "Applicazione mission critical"è qualsiasi applicazione in cui i difetti del prodotto Intel potrebbero causare, direttamente o indirettamente, lesioni personali o decesso. QUALORA SI ACQUISTASSERO O UTILIZZASSERO PRODOTTI INTEL PER QUALSIASI APPLICAZIONE MISSION CRITICAL, È NECESSARIO INDENNIZZARE E SOLLEVARE INTEL E LE SUE SOCIETÀ CONTROLLATE, SUBAPPALTATORI E AFFILIATI E I RESPONSABILI, FUNZIONARI E DIPENDENTI DI CIASCUNA DI QUESTE ENTITÀ, DA QUALSIASI RESPONSABILITÀ PER EVENTUALI COSTI PER RECLAMI, DANNI, SPESE E SPESE LEGALI RAGIONEVOLI DERIVANTI, DIRETTAMENTE O INDIRETTAMENTE, DA QUALSIASI RESPONSABILITÀ DEL PRODOTTO, LESIONE PERSONALE O DECESSO CAUSATI IN QUALSIASI MODO DA TALE APPLICAZIONE MISSION CRITICAL, INDIPENDENTEMENTE DAL FATTO CHE INTEL O IL PROPRIO SUBAPPALTATORE ABBIA AGITO IN MODO NEGLIGENTE NELLA PROGETTAZIONE, FABBRICAZIONE O AVVERTENZE DEL PRODOTTO INTEL O DI QUALSIASI SUO COMPONENTE.

Intel può apportare modifiche alle specifiche e alle descrizioni dei prodotti in qualsiasi momento e senza preavviso. I progettisti non devono fare affidamento sull'assenza o sulle caratteristiche di qualunque funzione o sulle istruzioni contrassegnate come "riservate" o "non definite". Intel si riserva di definirle in futuro e non accetta alcuna responsabilità in caso di conflitti o incompatibilità derivanti da ogni loro modifica futura. Le informazioni sono soggette a modifica senza preavviso. Non finalizzare un progetto con queste informazioni.

I prodotti descritti in questo documento possono contenere errori o difetti di progettazione noti come "errata" che possono determinare l'errato funzionamento del prodotto, a differenza di quanto stabilito nelle relative specifiche pubblicate. Gli "errata" attualmente riconosciuti sono disponibili su richiesta.

Per ottenere le specifiche più recenti e prima di inoltrare l'ordine di prodotti, contattare l'ufficio vendite Intel di zona oppure il distributore di fiducia.

Le copie dei documenti con numero d'ordine citati in questo documento, o altra letteratura Intel, possono essere richieste telefonando al numero (USA) 1-800-548-4725 oppure visitando il sito: http://www.intel.com/design/literature.htm * Altri marchi e denominazioni potrebbero essere proprietà di terzi.

 Copyright© 2012 Intel Corporation. Tutti i diritti riservati

Velocizzare l'emulatore Android* sull'architettura Intel®

$
0
0

Sunto:

Se siete uno sviluppatore di Android* che è insoddisfatto delle prestazioni dell'emulatore Android, allora questo documento fa per voi. Sappiamo delle continue lamentele degli sviluppatori di Android in merito all'emulatore che è lento e complesso da utilizzare. La situazione è però cambiata. Se usate un computer sufficientemente aggiornato con un processore Intel® che ha attivata la Intel® Virtualization Technology e che esegue Microsoft Windows* o Apple Mac OS*, potete allora usare Intel® Hardware Accelerated Execution Manager (Intel® HAXM) o KVM per Linux*, che è un modo semplice per accelerare notevolmente l'emulatore Android e, di conseguenza, le attività di test e debug delle applicazioni Android. Questo documento spiega tutti i passaggi richiesti per accelerare l'emulatore e come utilizzarlo. Spiega quindi come usare l'NDK per compilare il codice nativo x86 e il modo corretto per inviare gli APK contenenti le librerie native x86 allo store Google Play. Intel HAXM è anche usato per accelerare l'emulatore Tizen*, ma questo è un argomento che esula dall'ambito di questa documentazione. Per maggiori informazioni in merito, visitare tizen.org nella sezione dell'SDK.

Indice

1. Introduzione
2. Installazione
2.1. Prerequisiti
2.2. Installazione in Windows
2.3. Installazione in Linux
2.3.1. Installazione di KVM
2.4. Creazione di un AVD (Android* Virtual Device)
3. Metodologie ottimali
3.1. Testare l'applicazione con l'emulatore di Eclipse
3.2. Inviare più pacchetti APK per ABI diverse oppure inviare dei fat binary a Google Play
3.3. Compilare l'NDK per x86
3.3.1. Aggiungere il percorso dell'NDK alla variabile d'ambiente
3.3.2. Compilazione con l'NDK
3.3.3. Un altro modo per compilare con l'NDK

1. Introduzione

Questo documento offre le indicazioni per eseguire l’installazione di Intel® Hardware Accelerated Execution Manager (Intel® HAXM), un motore di virtualizzazione basato su hardware (hypervisor) che usa la Intel® Virtualization Technology (Intel® VT) per accelerare lo sviluppo Android* in Windows*. Spiega anche come configurare una macchina virtuale basata su kernel (KVM) e basata su hardware in Linux* e le metodologie ottimali per la compilazione nativa e l'invio di applicazioni allo store Google Play per x86.

2. Installazione

2.1. Prerequisiti

  • È necessario che l'Android SDK sia installato.
  • Il computer deve avere un processore Intel con il supporto per Intel VT-x, EM64T e la funzionalità Execute Disable(XD) Bit abilitata nel BIOS.

2.2. Installazione in Windows

Dopo aver installato l'Android SDK, aprire SDK Manager. È possibile trovare Intel HAXM nella sezione delle funzionalità aggiuntive.

Selezionare la casella e fare clic sul pulsante ‘Install packages…’ per installare il pacchetto. Non lasciarsi però trarre in inganno dallo stato visualizzato (‘Installed’), perché in realtà l'installazione non è avvenuta. L'SDK infatti copia sul computer solo il file eseguibile di Intel HAXM e sta a voi installarlo.

Per installare l'eseguibile di Intel HAXM, ricercare nel disco rigido il file IntelHaxm.exe (o IntelHAXM.dmg in Mac OS X). Se si sono lasciate invariate le impostazioni predefinite, il file dovrebbe trovarsi in C:\Programmi\Android\android-sdk\extras\Intel\Hardware_Accelerated_Execution_Manager\IntelHaxm.exe.

Intel HAXM funziona solo in combinazione con una delle immagini dei sistemi x86 basati sul processore Intel® Atom™, che sono disponibili per Android 2.3.3 (API 10), 4.0.3 (API 15), 4.1.2 (API 16), 4.2.2 (API 17). Queste immagini di sistema Intel possono essere installate esattamente come si fa per le immagini basate su ARM tramite l'SDK manager.

Quando si fa clic sull'eseguibile IntelHaxm, appare una schermata di benvenuto simile alla seguente:

È possibile regolare la quantità di memoria RAM da allocare a Intel HAXM. Dopo questa operazione, fare clic su Next. La schermata successiva conferma l'allocazione della memoria. Se tutte le informazioni sono quelle desiderate, fare clic su Install.

Per poter installare Intel HAXM, è necessario che Intel VT-x sia abilitato nel BIOS, altrimenti durante l'installazione sarà visualizzato un errore simile al seguente:

Se si riceve questo errore, entrare nel BIOS ed abilitare la funzione.

La seconda opzione per scaricare Intel HAXM e l'immagine dell'emulatore del sistema x86 è di andare direttamente al sito Web http://software.intel.com/it-it/android e da lì scaricare i componenti necessari.

2.3. Installazione in Linux

I passaggi per accelerare l'emulatore Android per Linux sono diversi da quelli per Windows e Mac OS X perché Intel HAXM non è compatibile con Linux ed è perciò necessario usare una macchina virtuale basata su kernel (KVM). I passaggi descritti di seguito sono stati eseguiti usando Ubuntu* 12.04 e potrebbero variare leggermente con altre distribuzioni Linux.

Come visto per Windows (e Mac OS X), è prima necessario scaricare l'Android SDK dal sito per sviluppatori Android. Si troverà un pacchetto ADT (Android Developer Tool) che contiene sia Eclipse* IDE che l'Android SDK. Scaricare il file zip ed estrarlo sul computer Linux. Accertarsi di usare la versione corretta per la propria distribuzione Linux, a 32 bit o a 64 bit. Lo si può verificare facilmente usando il comando:

file /sbin/init

Prima di iniziare a installare i pacchetti richiesti per KVM, si consiglia di accertarsi di avere l'ultimo repository digitando:

sudo apt-get update

2.3.1. Installazione di KVM

Per installare ed eseguire KVM, che è una soluzione completa di virtualizzazione per Linux su hardware x86 (ad esempio, Intel VT), è prima necessario controllare che la CPU supporti la virtualizzazione dell'hardware digitando:

egrep –c ‘(vmx|svm)’ /proc/cpuinfo

Se il risultato è 0, significa che la CPU non supporta la virtualizzazione dell'hardware, che è necessaria per eseguire la KVM. Se il risultato è 1 o un valore superiore, significa che si può procedere senza problemi, ma occorre sempre verificare che sia abilitata nel BIOS (vedere la Sezione 2.2).

Quindi si dovrà installare KVM, se non lo si è già installato. Si può verificare se il processore supporta KVM digitando:

kvm-ok

Se KVM è installato, sarà visualizzato questo messaggio:

"INFO: Your CPU supports KVM extensions
INFO: /dev/kvm exists
KVM acceleration can be used"

Altrimenti, sarà necessario andare nel BIOS e attivare Intel VT se appare il seguente messaggio:

"INFO: KVM is disabled by your BIOS
HINT: Enter your BIOS setup and enable Virtualization Technology (VT),
and then hard poweroff/poweron your system
KVM acceleration can NOT be used"

Nel passaggio successivo si installa la KVM e alcuni altri pacchetti necessari. A tal fine, digitare

sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils

Nella finestra successiva, selezionare No configuration se si desidera lasciare immutata la propria configurazione:

Quindi, aggiungere il proprio utente al gruppo KVM e al gruppo libvirtd. A tal fine, digitare:

sudo adduser proprio_nome_utente kvm
sudo adduser proprio_nome_utente libvirtd

Dopo l'installazione, eseguire nuovamente l'accesso cosicché le modifiche abbiano effetto. È possibile testare l'installazione digitando:

sudo virsh -c qemu:///system list

Si è ora pronti a continuare con il passaggio successivo in cui si crea ed esegue il dispositivo virtuale Android (AVD). La procedura è la stessa per Linux e Windows.

2.4. Creazione di un AVD (Android* Virtual Device)

Dopo aver installato l'SDK e Intel HAXM (o KVM in Linux), si può creare un dispositivo virtuale con emulazione accelerata da hardware. Al tal fine, andare in AVD Manager e creare un nuovo dispositivo. Accertarsi di selezionare Intel Atom (x86) come CPU/ABI. L'opzione appare nel menu a discesa solo se è installata l'immagine di sistema Intel x86. Per una maggiore fluidità della grafica, attivare l'emulazione della GPU mentre si crea l'AVD.

Fare clic su New e creare il dispositivo AVD x86. Accertarsi di selezionare un'API che sia supportata dalle immagini dei sistemi x86, di aver impostato l'opzione CPU/ABI a x86 e di aver abilitata l'emulazione della GPU (OpenGL ES*). Fatto questo, fare clic su Create AVD per creare il dispositivo virtuale Android.

È possibile avviare l'AVD x86 facendo clic su Start e quindi su Launch.

Se l'installazione riesce, all'avvio dell'emulatore appare una finestra di dialogo indicante che Intel HAXM è eseguito in modalità virtuale veloce.

Per accertarsi ulteriormente che l'immagine utilizzata sia di un sistema x86, è sempre possibile controllare le informazioni riportate in ‘About phone’ nell'emulatore.

L'aumento delle prestazioni che si osserverà con Intel HAXM o KVM dipende dal PC utilizzato, dall'unità, dalla memoria e da altri fattori, ma dovrebbe essere di un ordine di grandezza di 5-10 volte. La schermata seguente mostra il confronto tra un AVD abilitato x86/HAXM e un AVD basato su ARM. Il dispositivo AVD x86 si avvia nello schermo bloccato nel giro di 15 secondi mentre il dispositivo AVD non di Intel impiega 40 secondi, che è una differenza notevole.

[Con Intel HAXM (o KVM) si dovrebbe rilevare un aumento delle prestazioni di 5-10 volte, in base alla configurazione del sistema. Il software e i carichi di lavoro utilizzati nei test delle prestazioni potrebbero essere stati ottimizzati per le prestazioni solo sui microprocessori Intel. I test delle prestazioni, come SYSmark* e MobileMark*, sono misurati usando computer, componenti, software, operazioni e funzioni specifici. Qualunque modifica a questi fattori potrebbe causare variazioni nei risultati. Per valutare in modo più completo i prodotti considerati per l'acquisto, si consiglia di consultare altre informazioni e test delle prestazioni, incluse le prestazioni del prodotto quando usato insieme ad altri prodotti. Configurazione: in questo caso per i test è stato usato Mac Book Pro. Per maggiori informazioni andare a http://www.intel.com/performance”]

3. Metodologie ottimali

3.1. Testare l'applicazione con l'emulatore di Eclipse

Intel HAXM può essere utilizzato per velocizzare l'emulatore durante i test, sia che si tratti di un'applicazione basata su NDK che di un'applicazione Dalvik*. Se si sta sviluppando con Eclipse, seguire questa semplice procedura per accertarsi di usare Intel HAXM quando si avvia l'emulatore.

Accertarsi innanzitutto di creare l'AVD secondo le istruzioni date nel passaggio 2. Se l'AVD è pronto, andare a Run As -> Run Config come mostrato qui di seguito:

Dovrebbe aprirsi una pagina simile a questa:

In questa pagina è possibile scegliere l'AVD desiderato selezionando la casella corrispondente. Dopo aver creato l'AVD e impostata la configurazione, iniziare a compilare il progetto ed eseguirne il debug con l'emulatore selezionando Run As -> Android Application. In questo modo l'AVD accelerato da hardware si avvia automaticamente.

Dopo che l'AVD si è avviato, dovrebbe apparire la schermata iniziale dell'applicazione (occorre prima sbloccare lo schermo).

3.2. Inviare più pacchetti APK per ABI diverse oppure inviare dei fat binary a Google Play

In passato si sarebbe inviato un fat binary dell'applicazione sviluppata contenente tutte le librerie e i file NDK, senza poter differenziare tra le diverse architetture. In questo caso gli utenti avrebbero scaricato l'APK completo contenente anche i file non rilevanti per le architetture specifiche, ad esempio gli utenti x86 si sarebbero ritrovati con del codice ARM e viceversa. Lo svantaggio di questo metodo è che il fat binary ha dimensioni notevoli e l'utente è obbligato a scaricare una gran quantità di dati che non sono applicabili al dispositivo. È in genere accettabile se l'APK ha dimensioni inferiori ai 10-20 MB.

Intel e Google hanno implementato un meccanismo di filtro della CPU che, se ci si attiene al codice di versione consigliato mostrato qui di seguito, permette di inviare più APK contenenti le diverse librerie specifiche per ciascuna architettura.

La prima cifra si riferisce all'ABI, ad esempio 6 si riferisce all'architettura x86. Le cifre successive si riferiscono al livello di API che si intende utilizzare (11), alle dimensioni dello schermo (13) e quindi al numero di versione dell'applicazione (3.1.0).

Accertarsi che il numero di versione dell'applicazione contenga almeno 8 cifre e di assegnare le prima cifra più elevata alla versione x86. Nell'esempio precedente, si userebbe 6 per indicare x86, 2 per ARMv7 e 1 per ARMv5TE. In questo modo si permette che le versioni x86 siano quelle preferite dai dispositivi x86 e le versioni ARM siano quelle preferite dai dispositivi ARM.

Attenendosi a queste linee guida si assicura che gli utenti ottengano le prestazioni migliori dal dispositivo che usano. Si evita inoltre che gli utenti, a causa di errori di traduzione di codice, tentino di eseguire le applicazioni su dispositivi specifici.

Ulteriori informazioni sono reperibili all'indirizzo http://software.intel.com/it-it/articles/google-play-supports-cpu-architecture-filtering-for-multiple-apk.

3.3. Compilare l'NDK per x86

Questa sezione descrive come compilare la parte per x86 dell'NDK dell'applicazione.

Affinché l'applicazione basata su NDK possa essere eseguita su un dispositivo AVD x86 è necessario compilare la libreria NDK per l'architettura x86. A tal fine, seguire questa semplice procedura:

Aprire un prompt dei comandi e andare nella cartella dei file NDK, come mostrato sotto:

Accertarsi di aver impostato il percorso della variabile d'ambiente in modo da poter utilizzare lo script ndk-build da qualsiasi posizione.

3.3.1. Aggiungere il percorso dell'NDK alla variabile d'ambiente

Per impostare la variabile d'ambiente per l'NDK, fare clic su Computer e selezionare Properties. Andare alle proprietà di sistema Advanced e individuare le variabili d'ambiente (Environment Variables). Selezionare Path e fare clic su Edit. Alla fine della stringa ‘Variable Value’, aggiungere il percorso alla propria cartella principale dell'NDK, quella che contiene il file ndk-build.cmd come mostrato nell'immagine seguente:

3.3.2. Compilazione con l'NDK

Dal prompt dei comandi andare alla cartella dell'NDK ed eseguire:

ndk-build APP_ABI:=all

Il file NDK sarà eseguito per ciascuna architettura disponibile, ad esempio ARMv5TE, ARMv7, x86 e mips.

Per compilare per architetture specifiche, sostituire ‘all’ con le diverse architetture. Ad esempio:

ndk-build APP_ABI:=armeabi armeabi-v7a x86 mips

Accertarsi di aggiornare il progetto in Eclipse affinché siano acquisite le ultime impostazioni, come ad esempio le ultime cartelle create dallo script ndk-build. Nella cartella libs dei progetti dovrebbero ora essere presenti quattro cartelle, una per ciascuna architettura.

Si è ora pronti a usare l'AVD x86 con l'applicazione NDK.

3.3.3. Un altro modo per compilare con l'NDK

Un altro modo per compilare il codice nativo per tutte le architetture, inclusa l'architettura x86, è di modificare il file Application.mk che si trova nella cartella jni. Se il file Application.mk non è presente, lo si può creare e aggiungervi l'istruzione seguente:

APP_ABI:=armeabi armeabi-v7a x86 mips

In questo modo, quando si esegue il file batch, ad esempio lo script ndk-build, saranno compilate le librerie per tutte le architetture disponibili.

Inoltre, per semplificare l'uso, invece di elencare tutte le architetture basta indicare ‘all’:

APP_ABI:=all


Come abilitare la differenziazione per Miracast* di Intel® Wireless Display su un telefono con architettura Intel®

$
0
0

Introduzione

Da quando Google ha iniziato a supportare Miracast in Android 4.2, la tecnologia di visualizzazione wireless è stata adottata in misura crescente nei telefoni e nei tablet Android*. La tecnologia di visualizzazione wireless permette agli utenti di espandere con facilità le dimensioni dello schermo LCD del telefono. È molto probabile che in futuro gli ISV integrino la funzione di visualizzazione wireless nelle loro applicazioni, in particolare nei videogame e nei lettori video.

Ma come realizzare la differenziazione della visualizzazione wireless di Intel® per Miracast su Android per i telefoni x86 è una sfida importante per gli ISV che vogliono abilitare questa funzione. Questo articolo introduce come abilitare la differenziazione di due schermi per Miracast mostrando un caso di studio in cui si abilita un lettore video online iQiyi e WPS Office sul K900. Ci auguriamo che in futuro possano essere abilitate molte importanti applicazioni.

Cos'è Miracast

Il 19 settembre 2012 la Wi-Fi Alliance ha annunciato ufficialmente Wi-Fi* CERTIFIED Miracast, una soluzione innovativa per la visualizzazione diretta di video tra dispositivi, senza bisogno di cavi o di una connessione di rete. Gli utenti possono fare cose come guardare sullo schermo grande di un televisore le immagini o i video originati da uno smartphone, condividere in tempo reale lo schermo del notebook con il proiettore della sala conferenze e guardare su un tablet i programmi in diretta trasmessi dal decoder di casa. Le connessioni Miracast si formano usando Wi-Fi CERTIFIED Wi-Fi Direct*, quindi senza che sia necessario l'accesso ad una rete Wi-Fi perché la capacità di stabilire la connessione si trova all'interno dei dispositivi certificati Miracast.

Il collegamento Miracast si basa su una connessione Wi-Fi diretta, peer to peer. L'architettura Miracast basata su Wi-Fi è mostrata qui di seguito.



Figura 1: Architettura Miracast*

Vi sono quattro modalità di connessione Miracast, come illustrato di seguito:



Figura 2: Modalità di connessione Miracast*

La connessione Miracast permette il collegamento tra dispositivi senza che sia necessaria l'infrastruttura di un punto di accesso (AP) Wi-Fi, come mostra la topologia 1. È inoltre possibile collegarsi ad uno schermo tramite un adattatore durante la connessione a un punto di accesso (AP), come mostra la topologia 2. Questa modalità è molto utile per guardare i video online a casa. Se si dispone di un televisore intelligente che supporta anche Miracast, il televisore, il punto di accesso (AP) e lo smartphone possono anche collegarsi l'uno con l'altro, come mostrato nella topologia 4.

Secondo lo standard Miracast, la modalità interattiva dei dispositivi sorgente e dei dispositivi di visualizzazione può essere schematizzata come segue:



Figura 3: Gestione della sessione Miracast*

I dispositivi sorgente e i dispositivi di visualizzazione rilevano le reciproche capacità Miracast prima della configurazione della connessione. La connessione è basata su Wi-Fi diretto o TDLS. I dispositivi sorgente e i dispositivi di visualizzazione determinano i parametri per la sessione Miracast sulla base della negoziazione delle capacità. Per il processo di negoziazione è utilizzata la connessione TCP. I dispositivi sorgente trasferiscono il contenuto ai dispositivi di visualizzazione tramite il formato MPEG2-TS basato sulla connessione UDP.

I formati di streaming wireless Miracast supportati sono riportati nella Tabella 4.

Tabella 4: Formati di streaming Miracast*

Miracast su Android 4.2

Google ha iniziato a supportare Miracast in Android versione 4.2. Grazie alla tecnologia di visualizzazione wireless, gli utenti finali possono condividere su un apparecchio HDTV film, foto, video di YouTube e tutto ciò che appare sullo schermo. L'apparecchio HDTV esterno è riportato come uno schermo esterno.

Ora Miracast su Android supporta la modalità di clonazione e la modalità di presentazione, come mostrato di seguito:



Figura 5: Modalità supportate da Miracast*

La modalità di clonazione duplica lo schermo del telefono sullo schermo remoto. La risoluzione dei fotogrammi inviati all'adattatore corrisponde alla risoluzione dello schermo locale. In questa modalità, lo schemo locale e lo schermo remoto sono entrambi accesi e presentano lo stesso contenuto.

In modalità di presentazione, Android consente all'applicazione di visualizzare contenuti unici su schermi aggiuntivi che sono collegati al dispositivo dell'utente su una connessione cablata o Wi-Fi. Le applicazioni devono essere modificate per supportare questa modalità, altrimenti per impostazione predefinita viene usata la modalità di clonazione.

Sviluppare la differenziazione per Miracast su un telefono basato sull'architettura Intel

La soluzione di visualizzazione wireless di Intel sui telefoni e sui tablet Android è pienamente compatibile con Miracast. Abbiamo anche abilitato alcune applicazioni con utilizzi della differenziazione Miracast sui telefoni basati sull'architettura Intel.

Il primo è quello di consentire a iQiyi di realizzare la funzione di streaming video in background. Gli utenti possono inviare un video a uno schermo remoto con risoluzione 1080p utilizzando un'applicazione iQiyi che consente lo streaming in background e al contempo possono uscire dall'applicazione e sullo schermo locale riprodurre un video 1080p o utilizzare qualsiasi altra applicazione, compreso l'invio di e-mail o l'uso del browser senza causare interruzioni alla riproduzione in background, come mostrato di seguito:



Figura 6: Funzione video BGM iQiyi

Il secondo uso è quello di abilitare WPS Office per dividere la funzione dell'interfaccia utente sullo schermo locale e remoto. Quando ci si collega al televisore tramite la visualizzazione wireless, l'applicazione WPS Office abilitata può mostrare le diapositive di una presentazione PowerPoint sullo schermo remoto e visualizzare le note della presentazione sullo schermo del telefono, cosa molto comoda per il relatore. Abbiamo in programma di aggiungere in futuro un timer sullo schermo del telefono per segnalare il tempo al relatore.



Figura 7: Funzione WPS Office di divisione dell'interfaccia utente

Questi due utilizzi della differenziazione sono stati sviluppati basandosi sulla modalità di presentazione di Miracast e utilizzando le funzionalità hardware dell'architettura Intel del telefono. Le due applicazioni sono state caricate in Intel AppUp® dove gli utenti possano scaricarle e installarle sui telefoni basati sull'architettura Intel.

Caso di studio: come abilitare utilizzi della differenziazione con due schermi

Questa sezione descrive come realizzare una funzione di streaming video in background prendendo spunto da un caso reale di abilitazione di un'applicazione iQiyi.

Come sappiamo, la difficoltà fondamentale per realizzare la funzione video BGM è quella di ottenere un servizio che riproduca il video in background e tratti correttamente la visualizzazione della superficie o la visualizzazione del video. Quando l'utente preme il tasto home, la visualizzazione della superficie o del video viene automaticamente eliminata, ed è per questo motivo che è necessario applicare uno schermo secondario in cui visualizzare il video riprodotto in streaming in background. Il diagramma di flusso del programma è il seguente:



Figura 8: Diagramma di flusso per lo streaming di video in background

Per creare contenuti unici per uno schermo secondario, estendere la classe Presentation e implementare la chiamata onCreate(). All'interno di onCreate(), specificare l'interfaccia utente per lo schermo secondario con la chiamata a setContentView(). La classe Presentation, che è un'estensione della classe Dialog, offre l'area in cui l'applicazione è in grado di visualizzare un'interfaccia utente unica sullo schermo secondario.

È possibile utilizzare due metodi diversi per applicare lo schermo secondario di presentazione. Usare la API DisplayManager o la API MediaRouter. Il modo più semplice per scegliere la visualizzazione della presentazione è utilizzare l'API MediaRouter. Il servizio di router multimediale tiene traccia di quali percorsi audio e video sono disponibili sul sistema. Il router multimediale consiglia la visualizzazione di presentazione preferita che l'applicazione deve utilizzare per visualizzare contenuto sullo schermo secondario.

Ecco come utilizzare il router multimediale per creare e mostrare una presentazione nella visualizzazione di presentazione preferita utilizzando getPresentationDisplay().


 MediaRouter mediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
 MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();
 if (route != null) {
     Display presentationDisplay = route.getPresentationDisplay();
     if (presentationDisplay != null) {
         Presentation presentation = new MyPresentation(context, presentationDisplay);
         presentation.show();
     }
 }

Un altro modo per selezionare una visualizzazione di presentazione è utilizzare direttamente l'API DisplayManager. Il servizio display manager offre funzioni per enumerare e descrivere tutti gli schermi che sono collegati al sistema inclusi gli schermi che possono essere usati per le presentazioni.

Display manager tiene traccia di tutti gli schermi del sistema. Ecco come identificare gli schermi adatti per mostrare delle presentazioni usando getDisplays(String) e la categoria DISPLAY_CATEGORY_PRESENTATION.


 DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
 Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
 if (presentationDisplays.length > 0) {
      Display display = presentationDisplays[0];
     Presentation presentation = new MyPresentation(context, presentationDisplay);
     presentation.show();
 }

Gli sviluppatori possono fare riferimento al codice demo della presentazione in Android SDK, mostrato qui di seguito:

\sdk\sources\android-17\android\app\Presentation.java

Riepilogo

Oltre a essere un punto di forza per la vendita di Intel Inside® per i telefoni e i tablet basati sull'architettura Intel, la funzione di visualizzazione wireless può inoltre diventarne l'elemento guida. Gli ISV dovrebbero individuare e sviluppare gli utilizzi più innovativi basati sulla visualizzazione wireless, in particolare gli utilizzi di differenziazione di due schermi.

Riferimento

  1. http://www.wi-fi.org
  2. http://developer.android.com/about/versions/android-4.2.html
  3. Wi-Fi_Display_Technical_Specification_v1.0.0

Copyright © 2013 Intel Corporation. Tutti i diritti riservati.

*Altri marchi e denominazioni potrebbero essere proprietà di terzi.

Sviluppo di applicazioni per i sensori di telefoni e tablet Android* basati sul processore Intel® Atom™

$
0
0

Sviluppo di applicazioni per i sensori di telefoni e tablet Android* basati sul processore Intel® Atom™


Questa guida offre agli sviluppatori di applicazioni un'introduzione al framework dei sensori Android e tratta di come usare alcuni sensori che sono generalmente disponibili nei telefoni e nei tablet basati sul processore Intel® Atom™. Tra gli altri saranno trattati i sensori di movimento, di posizione e dell'ambiente. Questa guida parla anche dei servizi di localizzazione basati su GPS, sebbene il framework Android non classifichi strettamente il GPS come un sensore. Il contenuto esposto in questa guida si basa su Android 4.2, Jelly Bean.

Sensori di telefoni e tablet Android* basati sul processore Intel® Atom™


I telefoni e i tablet Android basati sui processori Intel Atom sono in grado di supportare una vasta gamma di sensori hardware. Questi sensori sono utilizzati per rilevare i cambiamenti di movimento e posizione e per riferire i parametri ambientali dell'ambiente. Lo schema a blocchi della Figura 1 mostra una possibile configurazione di sensori su un tipico dispositivo Android basato sul processore Intel Atom.


Figura 1.  Sensori di un sistema Android basato sul processore Intel® Atom™

Sulla base dei dati che riportano, i sensori Android possono essere classificati nelle classi e nei tipi indicati nella Tabella 1.

Sensori di movimentoAccelerometro
(TYPE_ACCELEROMETER)
Misura le accelerazioni di un dispositivo in m/s2Rilevazione del movimento
Giroscopio
(TYPE_GYROSCOPE)
Misura la velocità di rotazione di un dispositivoRilevazione della rotazione
Sensori di posizioneMagnetometro
(TYPE_MAGNETIC_FIELD)
Misura la forza del campo geomagnetico terrestre in µTBussola
Prossimità
(TYPE_PROXIMITY)
Misura la vicinanza di un oggetto in cmRilevamento di oggetti circostanti
GPS
 (non è un tipo di sensore android.hardware)
Ottiene la posizione geografica accurata del dispositivoRilevamento accurato della posizione geografica
Sensori dell'ambienteALS
(TYPE_LIGHT)
Misura il livello di luce ambientale in lxControllo automatico della luminosità dello schermo
BarometroMisura la pressione atmosferica dell'ambiente in mbarRilevamento dell'altitudine

Tabella 1.  Tipi di sensori supportati dalla piattaforma Android
 

Framework dei sensori Android


Il framework dei sensori Android fornisce meccanismi per accedere ai sensori e ai dati dei sensori, ad eccezione del GPS, tramite i servizi di localizzazione Android. Ne discuteremo più avanti in questo articolo. Il framework dei sensori fa parte del pacchetto android.hardware. La Tabella 2 elenca le principali classi e interfacce del framework dei sensori.

NomeTipoDescrizione
SensorManagerClasseUtilizzata per creare un'istanza del servizio del sensore. Fornisce diversi metodi per accedere ai sensori, registrare e deregistrare i listener di eventi dei sensori e così via.
SensoreClasseUtilizzata per creare un'istanza di un sensore specifico.
SensorEventClasseUtilizzata dal sistema per pubblicare i dati del sensore. Comprende i valori dei dati non elaborati del sensore, il tipo di sensore, l'accuratezza dei dati, la data e l'ora.
SensorEventListenerInterfacciaFornisce i metodi di callback per ricevere le notifiche di SensorManager quando i dati del sensore o la precisione del sensore cambiano.

Tabella 2. Il framework di sensori della piattaforma Android

Ottenere la configurazione del sensore

I produttori dei dispositivi decidono i sensori da rendere disponibili sul dispositivo. È necessario scoprire quali sensori sono disponibili in fase di esecuzione effettuando una chiamata al metodo getSensorList() del SensorManager del framework di sensori usando il parametro “Sensor.TYPE_ALL”. L'esempio di codice 1 mostra un elenco dei sensori disponibili e le informazioni relative al fornitore, alla potenza e alla precisione di ciascun sensore.

package com.intel.deviceinfo;
	
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Fragment;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
	
public class SensorInfoFragment extends Fragment {
	
    private View mContentView;
	
    private ListView mSensorInfoList;	
    SimpleAdapter mSensorInfoListAdapter;
	
    private List<Sensor> mSensorList;

    private SensorManager mSensorManager;
	
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
	
    @Override
    public void onPause() 
    { 
        super.onPause();
    }
	
    @Override
    public void onResume() 
    {
        super.onResume();
    }
	
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mContentView = inflater.inflate(R.layout.content_sensorinfo_main, null);
        mContentView.setDrawingCacheEnabled(false);
	
        mSensorManager = (SensorManager)getActivity().getSystemService(Context.SENSOR_SERVICE);
	
        mSensorInfoList = (ListView)mContentView.findViewById(R.id.listSensorInfo);
		
        mSensorInfoList.setOnItemClickListener( new OnItemClickListener() {
			
            @Override
            public void onItemClick(AdapterView<?> arg0, View view, int index, long arg3) {
				
                // with the index, figure out what sensor was pressed
                Sensor sensor = mSensorList.get(index);
				
                // pass the sensor to the dialog.
                SensorDialog dialog = new SensorDialog(getActivity(), sensor);

                dialog.setContentView(R.layout.sensor_display);
                dialog.setTitle("Sensor Data");
                dialog.show();
            }
        });
		
        return mContentView;
    }
	
    void updateContent(int category, int position) {
        mSensorInfoListAdapter = new SimpleAdapter(getActivity(), 
	    getData() , android.R.layout.simple_list_item_2,
	    new String[] {
	        "NAME",
	        "VALUE"
	    },
	    new int[] { android.R.id.text1, android.R.id.text2 });
	mSensorInfoList.setAdapter(mSensorInfoListAdapter);
    }
	
	
    protected void addItem(List<Map<String, String>> data, String name, String value)   {
        Map<String, String> temp = new HashMap<String, String>();
        temp.put("NAME", name);
        temp.put("VALUE", value);
        data.add(temp);
    }
	
	
    private List<? extends Map<String, ?>> getData() {
        List<Map<String, String>> myData = new ArrayList<Map<String, String>>();
        mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
		
        for (Sensor sensor : mSensorList ) {
            addItem(myData, sensor.getName(),  "Vendor: " + sensor.getVendor() + ", min. delay: " + sensor.getMinDelay() +", power while in use: " + sensor.getPower() + "mA, maximum range: " + sensor.getMaximumRange() + ", resolution: " + sensor.getResolution());
        }
        return myData;
    }
}

Esempio di codice 1. Frammento che mostra l'elenco dei sensori **

Sistema di coordinate dei sensori

Il framework dei sensori riporta i dati dei sensori usando un sistema standard di coordinate su tre assi, in cui i valori di X, Y e Z sono rispettivamente rappresentati da values[0], values[1] e values[2] dell'oggetto SensorEvent.

Alcuni sensori, come i sensori di luminosità, temperatura, prossimità e pressione, restituiscono solo valori singoli. Per questi sensori sono utilizzati solo i valori values[0] dell'oggetto SensorEvent.

Altri sensori riportano i dati nel sistema standard di coordinate a tre assi. I sensori di questo tipo sono:

  • Accelerometro
  • Sensore della gravità
  • Giroscopio
  • Sensore del campo geomagnetico

Il sistema di coordinate a tre assi del sensore è definito in relazione allo schermo del dispositivo secondo l'orientamento naturale (predefinito) del dispositivo. L'orientamento predefinito di un telefono è quello verticale, mentre l'orientamento naturale di un tablet è orizzontale. Quando il dispositivo è mantenuto nel suo orientamento naturale, l'asse x è orizzontale e punta verso destra, l'asse y è verticale e punta verso l'alto e l'asse z punta verso l'esterno del lato anteriore dello schermo. La Figura 2 mostra il sistema di coordinate del sensore per un telefono e la Figura 3 per un tablet.


Figura 2. Sistema di coordinate del sensore per un telefono


Figura 3.  Sistema di coordinate del sensore per un tablet

Il punto più importante per quanto riguarda il sistema di coordinate del sensore è che il sistema di coordinate del sensore non cambia quando il dispositivo si muove o cambia il suo orientamento.

Monitoraggio degli eventi del sensore

Il framework dei sensori riporta i dati dei sensori con gli oggetti SensorEvent. Una classe può monitorare i dati di uno specifico sensore implementando l'interfaccia SensorEventListener e registrando in SensorManager il sensore specifico. Il framework dei sensori comunica alla classe i cambiamenti di stato dei sensori tramite i seguenti due metodi di callback SensorEventListener implementati dalla classe:

 

onAccuracyChanged()

 

e

 

onSensorChanged()

 

L'esempio di codice 2 implementa il SensorDialog utilizzato nell'esempio SensorInfoFragment che abbiamo trattato nella sezione "Ottenere la configurazione del sensore".

package com.intel.deviceinfo;

import android.app.Dialog;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

public class SensorDialog extends Dialog implements SensorEventListener {
    Sensor mSensor;
    TextView mDataTxt;
    private SensorManager mSensorManager;

    public SensorDialog(Context ctx, Sensor sensor) {
        this(ctx);
        mSensor = sensor;
    }
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDataTxt = (TextView) findViewById(R.id.sensorDataTxt);
        mDataTxt.setText("...");
        setTitle(mSensor.getName());
    }
	
    @Override
    protected void onStart() {
        super.onStart();
        mSensorManager.registerListener(this, mSensor,  SensorManager.SENSOR_DELAY_FASTEST);
    }
		
    @Override
    protected void onStop() {
        super.onStop();
        mSensorManager.unregisterListener(this, mSensor);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() != mSensor.getType()) {
            return;
        }
        StringBuilder dataStrBuilder = new StringBuilder();
        if ((event.sensor.getType() == Sensor.TYPE_LIGHT)||
            (event.sensor.getType() == Sensor.TYPE_TEMPERATURE)||
            (event.sensor.getType() == Sensor.TYPE_PRESSURE)) {
            dataStrBuilder.append(String.format("Data: %.3fn", event.values[0]));
        }
        else{         
            dataStrBuilder.append( 
                String.format("Data: %.3f, %.3f, %.3fn", 
                event.values[0], event.values[1], event.values[2] ));
        }
        mDataTxt.setText(dataStrBuilder.toString());
    }
}

Esempio di codice 2.Finestra di dialogo che mostra i valori dei sensori**

Sensori di movimento

I sensori di movimento vengono utilizzati per monitorare il movimento del dispositivo, come ad esempio scuotimenti, rotazioni, oscillazioni o inclinazioni. L'accelerometro e il giroscopio sono due sensori di movimento disponibili su molti dispositivi tablet e telefoni.

I sensori di movimento segnalano i dati usando il sistema di coordinate del sensore, in cui i tre valori nell'oggetto SensorEvent, values[0], values[1] e values[2], rappresentano rispettivamente i valori delle assi x, y e z.

Per capire i sensori di movimento e usarne i dati in un'applicazione, è necessario applicare alcune formule di fisica legate alla forza, alla massa, all'accelerazione, le leggi del moto di Newton e il rapporto nel tempo tra alcune di queste entità. Per ulteriori informazioni su queste formule e relazioni, fare riferimento ai libri di testo di fisica o a fonti di pubblico dominio.

Accelerometro

L'accelerometro misura l'accelerazione applicata al dispositivo e le sue proprietà sono riassunte nella Tabella 3.

 
SensoreTipoDati
SensorEvent (m/s2)
Descrizione
AccelerometroTYPE_ACCELEROMETERvalues[0]
values[1]
values[2]
Accelerazione lungo l'asse x
Accelerazione lungo l'asse y
Accelerazione lungo l'asse z

Tabella 3. L'accelerometro

Il concetto di accelerometro deriva dalla seconda legge del moto di Newton:

a = F/m

L'accelerazione di un oggetto è il risultato della forza esterna netta applicata all'oggetto. Le forze esterne includono quella esercitata su tutti gli oggetti della terra, vale a dire la gravità. È proporzionale alla forza F applicata all'oggetto e inversamente proporzionale alla massa m dell'oggetto.

Nel nostro codice, anziché utilizzare direttamente l'equazione di cui sopra, siamo più interessati al risultato che l'accelerazione ha sulla velocità e sulla posizione del dispositivo in un determinato periodo di tempo. La seguente equazione descrive la relazione tra la velocità v1 di un oggetto, la sua velocità originale v0, l'accelerazione a e il tempo t:

v1 = v0 + at

Per calcolare lo spostamento s della posizione dell'oggetto usiamo la seguente equazione:

s = v0t + (1/2)at2

In molti casi si comincia con la condizione v0 uguale a 0 (prima che il dispositivo inizi a muoversi), che semplifica l'equazione nel modo seguente:

s = at2/2

La forza di gravità, rappresentata con il simbolo g sottopone tutti gli oggetti della terra ad accelerazione gravitazionale. Indipendentemente dalla massa dell'oggetto, il valore di g dipende solo dalla latitudine della posizione dell'oggetto ed è compreso tra 9,78 e 9,82 (m/s2). Adottiamo un valore standard convenzionale di g:

g = 9.80665 (m/s2)

Poiché l'accelerometro restituisce i valori utilizzando il sistema di coordinate di un dispositivo multidimensionale, nel nostro codice possiamo calcolare le distanze lungo gli assi x, y e z utilizzando le seguenti equazioni:

Sx = AxT2/2
Sy=AyT2/2
Sz=AzT2/2

Dove Sx, Sy e Sz sono rispettivamente gli spostamenti sull'asse x, sull'asse y e sull'asse z, mentre Ax, Ay e Az sono rispettivamente le accelerazioni sull'asse x, sull'asse y e sull'asse z. Tè il tempo del periodo di misurazione.

public class SensorDialog extends Dialog implements SensorEventListener {
    …	
    private Sensor mSensor;
    private SensorManager mSensorManager;
	
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    …
}

Esempio di codice 3. Istanza di un accelerometro**

A volte non usiamo i valori dei dati di tutte e tre le dimensioni. Altre volte potremmo anche avere bisogno di prendere in considerazione l'orientamento del dispositivo. Ad esempio, per un'applicazione labirinto, usiamo solo l'accelerazione gravitazionale dell'asse x e dell'asse y per calcolare la direzione del movimento e la distanza della pallina in base all'orientamento del dispositivo. La logica è descritta nel seguente frammento di codice (esempio di codice 4).

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
        return;
    } 
float accelX, accelY;
…
//detect the current rotation currentRotation from its “natural orientation”
//using the WindowManager
    switch (currentRotation) {
        case Surface.ROTATION_0:
            accelX = event.values[0];
            accelY = event.values[1];
            break;
        case Surface.ROTATION_90:
            accelX = -event.values[0];
            accelY = event.values[1];
            break;
        case Surface.ROTATION_180:
            accelX = -event.values[0];
            accelY = -event.values[1];
            break;
        case Surface.ROTATION_270:
            accelX = event.values[0];
            accelY = -event.values[1];
            break;
    }
    //calculate the ball’s moving distances along x, and y using accelX, accelY and the time delta
        …
    }
}

Esempio di codice 4.Considerare l'orientamento del dispositivo quando si utilizzano i dati dell'accelerometro in un gioco di labirinto**

Giroscopio


Il giroscopio calcola la velocità di rotazione del dispositivo intorno agli assi x, y e z, come mostrato nella Tabella 4. I valori dei dati del giroscopio possono essere positivi o negativi. Si supponga di guardare l'origine da una posizione lungo la metà positiva dell'asse, se la rotazione è in senso antiorario attorno all'asse, il valore è positivo, se la rotazione attorno all'asse è in senso orario, il valore è negativo. Possiamo anche determinare la direzione di un valore del giroscopio utilizzando la "regola della mano destra", illustrata nella Figura 4.


Figura 4.  Uso della “regola della mano destra” per decidere il senso di rotazione positivo

SensoreTipoDati
SensorEvent (rad/s)
Descrizione
GiroscopioTYPE_GYROSCOPEvalues[0]
values[1]
values[2]
Velocità di rotazione attorno all'asse x
Velocità di rotazione attorno all'asse y
Velocità di rotazione attorno all'asse z

Tabella 4. Il giroscopio

L'esempio di codice 5 mostra come creare un'istanza di giroscopio.

public class SensorDialog extends Dialog implements SensorEventListener {
    …	
    private Sensor mGyro;
    private SensorManager mSensorManager;
	
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mGyro = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
    …
}

Esempio di codice 5.Istanza di giroscopio**

Sensori di posizione

Molti tablet Android supportano due sensori di posizione: il magnetometro e i sensori di prossimità. Il magnetometro misura le forze del campo magnetico terrestre lungo gli assi x, y e z, mentre il sensore di prossimità rileva la distanza del dispositivo da un altro oggetto.

Magnetometro

L'uso più importante del magnetometro nei sistemi Android (descritto nella Tabella 5) è quello di implementare la bussola.

SensoreTipoDati
SensorEvent (µT)
Descrizione
MagnetometroTYPE_MAGNETIC_FIELDvalues[0]
values[1]
values[2]
Intensità del campo magnetico terrestre lungo l'asse x
Intensità del campo magnetico terrestre lungo l'asse y
Intensità del campo magnetico terrestre lungo l'asse z

Tabella 5. Il magnetometro

L'esempio di codice 6 mostra come creare un'istanza di magnetometro.

public class SensorDialog extends Dialog implements SensorEventListener {
    …	
    private Sensor mMagnetometer;
    private SensorManager mSensorManager;
	
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    …
}

Esempio di codice 6.Istanza di magnetometro**

Prossimità

Il sensore di prossimità fornisce la distanza tra il dispositivo e un altro oggetto. Il dispositivo può utilizzare il sensore per rilevare se il dispositivo viene tenuto vicino all'utente (vedere la Tabella 6), determinare se l'utente sta facendo una telefonata e quindi spegnere lo schermo durante la telefonata.

Tabella 6: Il sensore di prossimità
SensoreTipoDati
SensorEvent
Descrizione
ProssimitàTYPE_PROXIMITYvalues[0]Distanza da un oggetto in cm. Alcuni sensori di prossimità riportano solo un valore booleano per indicare se l'oggetto è abbastanza vicino.

Nell'esempio di codice 7 viene illustrato come creare un'istanza di un sensore di prossimità.

public class SensorDialog extends Dialog implements SensorEventListener {
    …	
    private Sensor mProximity;
    private SensorManager mSensorManager;
	
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    …
}

Esempio di codice 7.Istanza di un sensore di prossimità**

Sensori dell'ambiente

I sensori dell'ambiente rilevano e riportano parametri ambientali del dispositivo, quali la luce, la temperatura, la pressione o l'umidità. Il sensore della luce ambientale (ALS) e il sensore della pressione (barometro) sono disponibili su molti tablet Android.

Sensore della luce ambientale

Il sensore della luce ambientale, descritto nella Tabella 7, viene utilizzato dal sistema per rilevare l'illuminazione dell'ambiente circostante e di conseguenza regolare automaticamente la luminosità dello schermo.

Tabella 7: Il sensore della luce ambientale
SensoreTipoDati
SensorEvent (lx)
Descrizione
ALSTYPE_LIGHTvalues[0]L'illuminazione intorno al dispositivo

L'esempio di codice 8 mostra come creare un'istanza di ALS.

…	
    private Sensor mALS;
    private SensorManager mSensorManager;

    …	
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mALS = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    …

Esempio di codice 8.Istanza di un sensore della luce ambientale**

Barometro

Le applicazioni possono utilizzare il sensore della pressione atmosferica (barometro), descritto nella Tabella 8, per calcolare l'altitudine della posizione corrente del dispositivo.

Tabella 8: Il sensore della pressione atmosferica
SensoreTipoDati
SensorEvent (lx)
Descrizione
BarometroTYPE_PRESSUREvalues[0]La pressione atmosferica dell'ambiente in mbar

L'esempio di codice 9 mostra come creare un'istanza di barometro.

…	
    private Sensor mBarometer;
    private SensorManager mSensorManager;

    …	
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mBarometer = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
    …

Esempio di codice 9.  Istanza di barometro**

Linee guida per le prestazioni e l'ottimizzazione dei sensori

Seguire queste procedure ottimali per utilizzare i sensori nelle applicazioni:

  • Controllare sempre la disponibilità del sensore specifico prima di utilizzarlo
    La piattaforma Android non richiede che il dispositivo includa o escluda sensori specifici. Prima di utilizzare un sensore nell'applicazione, occorre sempre prima verificare se il sensore è effettivamente disponibile.
  • Deregistrare sempre i listener dei sensori
    Se l'attività che implementa il listener del sensore diventa invisibile o la finestra di dialogo si ferma, deregistrare il listener del sensore. Lo si può fare usando il metodo onPause() dell'attività o il metodo onStop() della finestra di dialogo. In caso contrario, il sensore continuerà ad acquisire dati scaricando di conseguenza la batteria.
  • Non bloccare il metodo onSensorChanged()
    Il metodo onSensorChanged() viene spesso chiamato dal sistema per riportare i dati del sensore. La logica inserita in questo metodo dovrebbe essere il più possibile ridotta al minimo. I calcoli complicati eseguiti utilizzando i dati del sensore devono essere spostati al di fuori di questo metodo.
  • Testare sempre sui dispositivi reali le applicazioni con sensori
    Tutti i sensori descritti in questa sezione sono sensori hardware. L'emulatore di Android potrebbe non essere in grado di simulare le funzioni e le prestazioni di un particolare sensore.

GPS e localizzazione


GPS (Global Positioning System) è un sistema satellitare che fornisce informazioni accurate di geolocalizzazione in tutto il mondo. Il GPS è disponibile in molti telefoni Android e tablet. Sotto molti aspetti il GPS si comporta come un sensore di posizione. È in grado di fornire dati di posizione accurati per le applicazioni in esecuzione sul dispositivo. Nella piattaforma Android il GPS non è gestito direttamente dal framework dei sensori. Il servizio di localizzazione Android invece accede ai dati del GPS e li trasferisce a un'applicazione tramite le chiamate del listener della posizione.

Questa sezione descrive il GPS e i servizi di localizzazione solo dal punto di vista del sensore hardware. Le strategie di localizzazione complete offerte da Android 4.2 e dai telefoni e tablet Android basati sul processore Intel Atom sono un argomento molto più vasto che esula dall'ambito della presente sezione.

Servizi di localizzazione Android

L'utilizzo del GPS non è l'unico modo per ottenere informazioni sulla posizione di un dispositivo Android. Il sistema può anche utilizzare la connessione Wi-Fi*, le reti cellulari o altre reti wireless per ottenere la posizione corrente del dispositivo. Il GPS e le reti wireless (tra cui le reti Wi-Fi e le reti cellulari) agiscono come “fornitori della posizione” per i servizi di localizzazione Android. La Tabella 9 elenca le principali classi e interfacce utilizzate per accedere ai servizi di localizzazione Android.

Tabella 9: Il servizio di localizzazione della piattaforma Android
NomeTipoDescrizione
LocationManagerClasseUtilizzata per accedere ai servizi di localizzazione. Fornisce i vari metodi per la richiesta di aggiornamenti periodici della posizione di un'applicazione o per l'invio di avvisi di prossimità
LocationProviderClasse astrattaLa super classe astratta per i provider di localizzazione
LocationClasseUtilizzata dai provider di localizzazione per incapsulare dati geografici
LocationListenerInterfacciaUtilizzata per ricevere le notifiche di localizzazione dal LocationManager

Ottenere aggiornamenti sulla posizione GPS

Per ricevere gli aggiornamenti sulla posizione GPS l'applicazione implementa diversi metodi di callback definiti nell'interfaccia LocationListener, in modo simile al meccanismo che utilizza il framework dei sensori per accedere ai dati del sensore. LocationManager invia all'applicazione le notifiche degli aggiornamenti GPS attraverso questi callback (secondo la regola “Non chiamateci, vi chiameremo noi”).

Per accedere ai dati di posizione GPS nell'applicazione è necessario richiedere il permesso di accesso alla posizione precisa nel file manifesto di Android (esempio di codice 10).

<manifest …>
…
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
…  
</manifest>

Esempio di codice 10.Richiesta del permesso di accesso alla posizione precisa nel file manifesto**

L'esempio di codice 11 mostra come ottenere gli aggiornamenti GPS e visualizzare le coordinate della latitudine e della longitudine come testo di una finestra di dialogo.

package com.intel.deviceinfo;

import android.app.Dialog;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class GpsDialog extends Dialog implements LocationListener {
    TextView mDataTxt;
    private LocationManager mLocationManager;
	
    public GpsDialog(Context context) {
        super(context);
        mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
	       mDataTxt = (TextView) findViewById(R.id.sensorDataTxt);
          mDataTxt.setText("...");
		
        setTitle("Gps Data");
    }
	
    @Override
    protected void onStart() {
        super.onStart();
        mLocationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, 0, 0, this);
    }
		
    @Override
    protected void onStop() {
        super.onStop();
        mLocationManager.removeUpdates(this);
    }

    @Override
    public void onStatusChanged(String provider, int status, 
        Bundle extras) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onLocationChanged(Location location) {
        StringBuilder dataStrBuilder = new StringBuilder();
        dataStrBuilder.append(String.format("Latitude: %.3f,   Logitude%.3fn", location.getLatitude(), location.getLongitude()));
        mDataTxt.setText(dataStrBuilder.toString());
		
    }
}

Esempio di codice 11.  Una finestra di dialogo che visualizza i dati di posizione GPS**

Linee guida per le prestazioni e l'ottimizzazione del GPS e della posizione

Il GPS fornisce le informazioni più accurate sulla posizione del dispositivo. Trattandosi tuttavia di una funzionalità hardware, consuma energia supplementare. Il GPS impiega anche del tempo per ottenere la prima posizione fissa. Ecco alcune linee guida da seguire durante lo sviluppo di applicazioni GPS in grado di rilevare la posizione:

  • Considerare tutti i provider di localizzazione disponibili
    Oltre a GPS_PROVIDER, vi è NETWORK_PROVIDER. Se le applicazioni hanno bisogno solo di dati di localizzazione geografica non puntuali, si può prendere in considerazione di utilizzare NETWORK_PROVIDER.
  • Utilizzare le posizioni memorizzate nella cache
    Il GPS impiega del tempo per ottenere la prima posizione fissa. Quando l'applicazione è in attesa che il GPS ottenga un aggiornamento preciso della posizione, è possibile usare le posizioni fornite dal metodo getlastKnownLocation() di LocationManager per svolgere parte del lavoro.
  • Ridurre al minimo la frequenza e la durata delle richieste di aggiornamento della posizione
    Richiedere l'aggiornamento della posizione solo quando è necessario e prontamente deregistrare la richiesta dal location manager una volta che non c'è più bisogno di ottenere gli aggiornamenti della posizione.

Riepilogo


La piattaforma Android fornisce agli sviluppatori le API per accedere ai sensori integrati nei dispositivi. Questi sensori sono in grado di fornire dati grezzi sul movimento, sulla posizione e sulle condizioni ambientali correnti del dispositivo con elevata precisione e accuratezza. Nello sviluppo di applicazioni per i sensori, è necessario seguire le pratiche ottimali per migliorare le prestazioni e l'efficienza energetica.

Informazioni sull'autore

Miao Wei è un ingegnere informatico del gruppo software e servizi presso Intel. Attualmente sta lavorando a progetti di abilitazione della scalabilità del processore Intel® Atom™.



 

 

 

Copyright © 2013 Intel Corporation. Tutti i diritti riservati.
*Altri marchi e denominazioni potrebbero essere proprietà di terzi.

**Questo codice sorgente di esempio è rilasciato in base al Contratto di licenza per il codice sorgente di esempio Intel

Sviluppo di applicazioni Android* con funzionalità di riconoscimento vocale

$
0
0

di Stanislav Pavlov

Android non è in grado di riconoscere il parlato, quindi anche un dispositivo Android tipico non può riconoscere il parlato. Oppure, esiste un modo in cui possa farlo?

Il modo più semplice è quello di chiedere a un'altra applicazione di eseguire il riconoscimento vocale. Quando in Android si chiede a un'altra applicazione di fare qualcosa si dice che si utilizzano intent.

Il nostro dispositivo di destinazione deve avere almeno un'applicazione in grado di elaborare l'Intent per il riconoscimento vocale, che viene chiamato dall'azione RecognizerIntent.ACTION_RECOGNIZE_SPEECH.

Una di queste applicazioni è Google Voice Search. Si tratta di uno dei migliori riconoscitori disponibili per Android e supporta numerose lingue. Questo servizio richiede una connessione a Internet, perché il riconoscimento vocale avviene sui server di Google. Questa applicazione è una Activity molto semplice che informa gli utenti che possono parlare. Nel momento in cui l'utente smette di parlare, la finestra viene chiusa e la nostra applicazione (chiamante dell'intent) riceve una matrice di stringhe del parlato riconosciuto.

Esempio di riconoscimento vocale

Scriviamo una piccola applicazione di esempio che dimostra la ricerca vocale nelle applicazioni.

L'applicazione deve eseguire quanto segue:

  • Ricevere una richiesta di riconoscimento vocale
  • Verificare la disponibilità dell'applicazione di riconoscimento vocale
  • Se il riconoscimento vocale è disponibile, deve chiamarne l'intent e ricevere i risultati
  • Se il riconoscimento vocale non è disponibile, deve mostrare la finestra di dialogo per l'installazione di Google Voice Search e reindirizzare l'utente a Google Play, se lo desidera

In primo luogo, creiamo una classe che implementa la logica per il riconoscimento vocale. Chiamare questa classe SpeechRecognitionHelper dove dichiariamo una funzione pubblica statica run() che riceverà la richiesta di avvio di un riconoscimento:

/**
 * A helper class for speech recognition
 */
public class SpeechRecognitionHelper {

/**
     * Running the recognition process. Checks availability of recognition Activity,
     * If Activity is absent, send user to Google Play to install Google Voice Search.
    * If Activity is available, send Intent for running.
     *
     * @param callingActivity = Activity, that initializing recognition process
     */
    public static void run(Activity callingActivity) {
        // check if there is recognition Activity
        if (isSpeechRecognitionActivityPresented(callingActivity) == true) {
            // if yes – running recognition
            startRecognition(callingActivity);
        } else {
            // if no, then showing notification to install Voice Search
            Toast.makeText(callingActivity, "In order to activate speech recognition you must install \"Google Voice Search\"", Toast.LENGTH_LONG).show();
            // start installing process
            installGoogleVoiceSearch(callingActivity);
        }
    }
}

Come potete vedere, oltre alla funzione run() dobbiamo implementare altre tre funzioni:

  • isSpeechRecognitionActivityPresented – verifica se l'applicazione di riconoscimento vocale è presente nel sistema
  • installGoogleVoiceSearch – inizializza il processo di installazione di Google Voice Search
  • startRecognition – prepara l'intent appropriato ed esegue il riconoscimento

Per controllare se il dispositivo dispone di un'applicazione per il riconoscimento vocale, possiamo usare il metodo queryIntentActivities nella classe PackageManager. Questo metodo fornisce un elenco di attività che possono elaborare l'intent specificato. Per ricevere un'istanza di PackageManager, possiamo usare getPackageManager.

Il nostro codice è riportato di seguito:

isSpeechRecognitionActivityPresented

/**
     * Checks availability of speech recognizing Activity
     *
     * @param callerActivity – Activity that called the checking
     * @return true – if Activity there available, false – if Activity is absent
     */
    private static boolean isSpeechRecognitionActivityPresented(Activity callerActivity) {
        try {
            // getting an instance of package manager
            PackageManager pm = callerActivity.getPackageManager();
            // a list of activities, which can process speech recognition Intent
            List activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);

            if (activities.size() != 0) {    // if list not empty
                return true;                // then we can recognize the speech
            }
        } catch (Exception e) {

        }

        return false; // we have no activities to recognize the speech
    }

Ora implementare la funzione startRecognition. Questa funzione formerà l'intent appropriato per l'attività di avvio del riconoscimento vocale. Nella pagina della documentazioneè possibile trovare informazioni dettagliate su come farlo.

Codice sorgente:

   /**
     * Send an Intent with request on speech 
     * @param callerActivity  - Activity, that initiated a request
     */
    private static void startRecognitionActivity(Activity callerActivity) {

        // creating an Intent with “RecognizerIntent.ACTION_RECOGNIZE_SPEECH” action
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        // giving additional parameters:
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Select an application");    // user hint
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);    // setting recognition model, optimized for short phrases – search queries
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);    // quantity of results we want to receive
//choosing only 1st -  the most relevant 

        // start Activity ant waiting the result
        ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);
    }

E per ultimo implementeremo la funzione installGoogleVoiceSearch. Questa funzione mostrerà la finestra di dialogo che chiede all'utente se vuole installare Google Voice Search e, in caso affermativo, lo indirizza a Google Play.

/**
     * Asking the permission for installing Google Voice Search. 
     * If permission granted – sent user to Google Play
     * @param callerActivity – Activity, that initialized installing
     */
    private static void installGoogleVoiceSearch(final Activity ownerActivity) {

        // creating a dialog asking user if he want
        // to install the Voice Search
        Dialog dialog = new AlertDialog.Builder(ownerActivity)
            .setMessage("For recognition it’s necessary to install \"Google Voice Search\"")    // dialog message
            .setTitle("Install Voice Search from Google Play?")    // dialog header
            .setPositiveButton("Install", new DialogInterface.OnClickListener() {    // confirm button

                // Install Button click handler
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    try {
                        // creating an Intent for opening applications page in Google Play
                        // Voice Search package name: com.google.android.voicesearch
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
                        // setting flags to avoid going in application history (Activity call stack)
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                        // sending an Intent
                        ownerActivity.startActivity(intent);
                     } catch (Exception ex) {
                         // if something going wrong
                         // doing nothing
                     }
                }})

            .setNegativeButton("Cancel", null)    // cancel button
            .create();

        dialog.show();    // showing dialog
    }

Questo è tutto. Eseguiamo l'attività di riconoscimento vocale. Quindi richiediamo all'utente l'autorizzazione per installare Voice Search e, se l'utente acconsente, lo indirizziamo a Google Play. Una cosa che ci rimane da fare è raccogliere i risultati del riconoscimento vocale.

Inviamo una richiesta utilizzando la funzione startActivityForResult per raccogliere i risultati dell'attività avviata. Abbiamo anche bisogno di ridefinire un metodo OnActivityResult nell'attività del chiamante dell'intent. Lo si può realizzare nel modo seguente:

// Activity Results handler
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        // if it’s speech recognition results
        // and process finished ok
        if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {

            // receiving a result in string array
            // there can be some strings because sometimes speech recognizing inaccurate
            // more relevant results in the beginning of the list
            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            // in “matches” array we holding a results... let’s show the most relevant
            if (matches.size() > 0) Toast.makeText(this, matches.get(0), Toast.LENGTH_LONG).show();
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

Ora siamo pronti

La classe creata SpeechRecognitionHelper ci permette di effettuare una richiesta di riconoscimento vocale chiamando una sola funzione run().

Tutto ciò che occorre fare per aggiungere una funzione di riconoscimento è aggiungere questa classe nel nostro progetto e richiamare la funzione run nel punto necessario. Implementare quindi l'elaborazione del testo dei risultati ridefinendo il metodo onActivityResult per l'attività che ha avviato la chiamata di riconoscimento.

Per ulteriori informazioni è possibile consultare il sito Web degli sviluppatori Android. Si possono trovare esempi interessanti che mostrano come fare il riconoscimento vocale, e soprattutto, come ottenere l'elenco delle lingue disponibili. Questo elenco è utile per il riconoscimento di lingue diverse da quella dell'impostazione locale predefinita dell'utente.

Per integrare rapidamente l'input vocale nell'applicazione, è possibile scaricare e utilizzare questo codice per la classe SpeechRecognitionHelper.

Informazioni sugli autori

Stanislav lavora nel gruppo software e servizi presso Intel Corporation. Ha oltre 10 anni di esperienza nello sviluppo di software. Il suo interesse principale è l'ottimizzazione delle prestazioni, del consumo di energia e della programmazione parallela. Nel suo attuale ruolo di ingegnere di applicazioni, in cui fornisce supporto tecnico per i dispositivi basati su Intel, Stanislav lavora in stretto contatto con gli sviluppatori di software e i progettisti SoC per aiutarli a raggiungere le prestazioni migliori possibili sulle piattaforme Intel. Stanislav ha conseguito un Master in Economia matematica presso la Scuola Superiore delle Scienze economiche dell'Università Nazionale di Ricerche.

Mikhail è co-autore di questo blog ed è uno stagista estivo presso Intel che sta studiando informatica all'Università Lobachevskij. Gli piace immergersi nella matematica ed escogitare trucchi di programmazione Android.

 

Intel e il logo Intel sono marchi di Intel Corporation registrati negli Stati Uniti e/o in altri paesi.
Copyright © 2013 Intel Corporation. Tutti i diritti riservati.
*Altri marchi e denominazioni potrebbero essere proprietà di terzi.

Sviluppo e ottimizzazione di applicazioni videogame Android usando NDK su piattaforme basate sull'architettura Intel®

$
0
0

Android Native Development Kit (NDK) è uno strumento complementare dell'Android SDK che consente di implementare parti dell'applicazione usando linguaggi in codice nativo come C e C++.

È possibile scaricare il toolkit NDK da questo sito: http://developer.android.com/tools/sdk/ndk/index.html

NDK per l'architettura del set di istruzioni X86

Android è un sistema operativo open source sviluppato da Google. Attualmente Android può essere eseguito su tre famiglie di architetture di set di istruzioni: ARM, x86 e MIPS. X86 denota una famiglia di architetture di set di istruzioni basate sulla CPU Intel 8086 introdotta nel 1978. Esaminiamo ora dal punto di vista applicativo quali sono le differenze tra X86 (chiamata anche architettura Intel® o IA) e gli altri chipset su cui è eseguito Android.

Le applicazioni Android possono essere classificate in due tipi:

  • Le applicazioni Dalvik che includono codice Java* e usano solo l'API dell'Android SDK ufficiale e i file di risorse necessari, come .xml e .png, compilati in un file APK.
  • Le applicazioni Android NDK che includono il codice Java e i file di risorse nonché il codice sorgente C/C++ e talvolta il codice assembly. Tutto il codice nativo è compilato in una libreria dinamica (file .so) e quindi chiamato da Java nel programma principale usando un meccanismo JNI.

Motore per videogame Android

Il motore per videogame è un modulo fondamentale per le applicazioni videogame. Esistono diversi motori che funzionano con Android, inclusi motori 2D e 3D, che sono open source e motori commerciali. Pertanto, è difficile eseguire la migrazione e sviluppare videogame basati su Android che siano eseguiti sulla piattaforma basata sull'architettura Intel. Cocos2d-x e Unity 3D sono i motori per videogame più diffusi per le piattaforme Android.

Cocos2d-x si basa su Cocos2d-iPhone e consiste nell'espansione delle piattaforme supportate, con più linguaggi di programmazione che condividono la stessa struttura di API. Dalla sua introduzione nel luglio 2010, cocos2d-x è stato scaricato oltre 500 milioni di volte. I giganti nel settore dei giochi per dispositivi portatili come Zynga, Glu, GREE, DeNA, Konami, TinyCo, Gamevil, HandyGames, Renren Games, 4399, HappyElements, SDO e Kingsoft stanno usando cocos2d-x.

Unity 3D è un motore per videogame cross-platform con un IDE integrato sviluppato da Unity Technologies. È utilizzato per sviluppare videogame per plugin Web, piattaforme desktop, console e dispositivi mobili ed è utilizzato da oltre un milione di sviluppatori. Dallo strumento di sviluppo di videogame supportato da OS X del 2005 si è evoluto in un motore per videogame multi-piattaforma. Nel marzo del 2013 è stato rilasciato Unity 4.1, che è l'aggiornamento più recente. Attualmente supporta lo sviluppo per iOS, Android, Windows, Blackberry 10, OS X, Linux, browser Web, Flash*, PlayStation 3, Xbox 360, Windows Phone e Wii.

Sviluppo di videogame con Android NDK per piattaforme basate su architettura Intel

Prima di parlare di sviluppo di videogame, dovremmo parlare della piattaforma Android in generale. Come sapete, i videogame sono disponibili in molti stili diversi. I diversi stili di videogame hanno bisogno di principi di progettazione diversi. Di solito si decide il genere del videogame all'inizio del progetto. A meno che non abbiate inventato qualcosa di completamente nuovo e inedito, è molto probabile che il videogame che intendete realizzare si inserisca in uno dei generi attualmente più diffusi. La maggior parte dei generi ha standard stabiliti per il meccanismo di gioco (ad esempio, sistemi di controllo, obiettivi specifici, ecc.). La deviazione da questi standard può determinare il successo di un videogame poiché i videogamer sono sempre alla ricerca di qualcosa di nuovo. Alcuni generi comuni sono:

  • Arcade e azione
  • Rompicapo e puzzle
  • Carte e casinò
  • Casual
  • Live Wallpaper
  • Corse
  • Giochi di sport
  • Widget
  • ecc.

Il processo per sviluppare videogame Android generali è simile a quello usato per qualsiasi altra applicazione Android. In primo luogo, occorre scaricare l'SDK e l'NDK di Android dal sito Web di Google e installarli in modo corretto.

Si presume che sia stato già fatto tutto il lavoro di installazione e preparazione. Vediamo ora come creare un videogame per l'architettura Intel usando come esempio il motore per videogame Cocos2d-x.

Scaricare Cocos2D-x

Scaricare la versione stabile più recente di Cocos2D-x dal sito Web: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Download

Eseguire il file batch

Eseguire il file batch da Esplora risorse di Windows. Quando viene richiesto il percorso del progetto, impostare un percorso simile a com.tuoprogetto.qualcosa e scegliere il nome del progetto e l'ID di destinazione. Così facendo si creerà una cartella con il nome del progetto all'interno della cartella di installazione di cocos2dx. Si dovrebbe vedere l'esecuzione di uno script senza errori, simile al seguente:

Impostare le variabili d'ambiente di NDK_ROOT

Aggiungere le seguenti variabili d'ambiente alla fine del file home\<tuonome>\.bash_profile (in questo caso:c:\cygwin\home\user\.bash_profile):

NDK_ROOT=/cygdrive/<tuonome>/

export NDK_ROOT
 

riavviare cygwin, inserire cd $NDK_ROOT e dovrebbe apparire la schermata:

Eseguire il file build_native.sh

La configurazione predefinita è ARM e dobbiamo cambiarla affinché compili per x86. Aprire il file \helloworld\proj.android \build_native.sh, trovare il comando ndk-build e aggiungere il parametro APP_ABI=x86 alla fine del comando. Eseguirlo in Cygwin e si vedrà:

Importare il progetto in Eclipse

Andare quindi in Eclipse e creare un nuovo progetto importandolo da un progetto esistente.

Compilare ed eseguire

A questo punto, Eclipse avrà alcuni problemi:

The import org.cocos2dx.lib cannot be resolved HelloWorld.java

/HelloWorld/src/com/young40/test line 26 Java Problem Cocos2dxActivity cannot be resolved to a type HelloWorld.java

/HelloWorld/src/com/young40/test line 30 Java Problem Cocos2dxActivity cannot be resolved to a type HelloWorld.java

/HelloWorld/src/com/young40/test line 33 Java Problem

È necessario importare la seguente libreria in Eclipse come progetto:

cocos2d-2.1beta3-x-2.1.1/cocos2dx/platform/android/java

Andare a Project -> Build e quindi selezionare Run As -> Android Application:

Verrà quindi creato un framework per lo sviluppo di giochi per il motore per videogame cocos2dx. Al progetto è possibile aggiungere risorse quali la logica di gioco, audio, foto e così via per creare un videogame completo.

Ottimizzare videogame basati sull'Android NDK su piattaforme con architettura Intel

Intel® System Studio è una suite di strumenti per eseguire il profiling e l'ottimizzazione delle applicazioni sulle piattaforme Android. Naturalmente possiamo usarla per ottimizzare i videogame. Intel System Studio comprende:

  • Compilatore C++ Intel®
  • Intel® Graphics Performance Analyzers
  • Intel® VTune™ Amplifier
  • (Debugger Intel® JTAG )

In questo articolo non descriveremo dettagliatamente questi strumenti. Descriveremo invece un esempio che mostra il funzionamento degli strumenti di Intel.

In primo luogo, prendiamo un'applicazione chiamata Bounding Ball che verrà eseguita su un processore Intel® Atom™ Z2460 (nome in codice Medfield). Il gioco ha più di 800 sfere che si muovono a velocità casuale e collidono tra loro senza alcuna regolarità. Possiamo vedere che le prestazioni non sono buone misurando il valore di FPS, che è solo 6 senza alcuna ottimizzazione.

Possiamo usare Intel® Graphics Performance Analyzers (Intel® GPA) per individuare quale modulo è il collo di bottiglia e scoprire se si tratta di un limite della CPU o della GPU.

La schermata Intel GPA qui sotto mostra un grafico che riporta i dettagli di questa applicazione ottenuti usando GPA su piattaforma Android e da cui si può vedere che la CPU consuma il 52,5% delle risorse. Questa è una percentuale piuttosto alta per una singola applicazione. I valori di ISP Load, TA Load, TSP Load e USSE Total Load in esecuzione all'interno della GPU sono invece tutti inferiori al 10%, il che significa che il carico della GPU è normale. Possiamo perciò concludere che il collo di bottiglia è nel modulo CPU. Per analizzare ulteriormente la questione del collo di bottiglia della CPU, dobbiamo profilare il codice utilizzando l'analizzatore VTune™.

In questa sede non descriveremo come utilizzare l'analizzatore VTune, ma spiegheremo semplicemente i risultati che abbiamo ottenuto utilizzandolo. Gli hotspot sono le funzioni sin e cos all'interno di libm.so. La domanda da porsi quindi è: perché l'applicazione spende così tanto tempo e cicli di CPU per eseguire queste due funzioni?

Controllando il codice sorgente dell'applicazione, scopriamo che queste due funzioni hotspot sono richiamate quando OpenGL ES* esegue il rendering di ogni sfera. Le sfere hanno tutte la stessa forma, solo la dimensione è diversa. Possiamo perciò duplicare le sfere usando la funzione glScale di OpenGL in modo da ridurre notevolmente la funzione hotspot.

Dopo l'ottimizzazione del codice, le prestazioni migliorano dell'80% e il valore di FPS è 14. Inoltre, siamo in grado di compilare l'applicazione con il compilatore C/C++ Intel per ottenere prestazioni migliori sulle piattaforme con architettura Intel. Il compilatore C/C++ Intel ha molti flag per ottimizzare le prestazioni sulle piattaforme con architettura Intel. Qui ne presentiamo solo alcuni.

  • SSSE3_ATOM
    Supplemental Streaming SIMD Extensions 3 (SSSE3 o SSE3S) è un set di istruzioni SIMD creato da Intel ed è la quarta iterazione della tecnologia SSE.
  • IPO
    Il flag Interprocedural Optimization riduce il carico di lavoro delle chiamate di funzione, elimina il codice non utilizzato e riordina la propagazione delle costanti e la procedura.
  • PGO
    Il flag Profile-Guided Optimizations analizza e lascia molte domande aperte per l'ottimizzatore, quali:
    • Quanto è frequente x > y
    • Quali sono le dimensioni del conteggio
    • Quale codice è coinvolto e con quale frequenza

Il compilatore C/C++ Intel può anche migliorare le applicazioni come segue:

  • Previsione più accurata dei salti condizionati
  • Spostamento dei blocchi di base per migliorare il comportamento della cache di istruzioni
  • Decisione migliore per le funzioni inline (guida IPO)
  • Ottimizzazione migliore dell'ordinamento delle funzioni
  • Ottimizzazione delle istruzioni switch
  • Migliori decisioni di vettorizzazione

Utilizzando diversi compilatori e diversi parametri di compilazione, si possono ottenere prestazioni diverse da una stessa applicazione. Ecco il confronto delle prestazioni di due compilatori, GCC e ICC. La stessa applicazione Bounding Ball è in esecuzione su un telefono Android basato su Intel Medfield. La parte blu indica le prestazioni di GCC e quella rossa le prestazioni di ICC. La base di riferimento è la compilazione senza parametri. La seconda parte del grafico mostra la compilazione con arch=atom. La terza parte è la ricompilazione con tutti i parametri di cui sopra. Infine, è possibile vedere che le prestazioni dell'applicazione compilata da ICC sono del 60% superiori rispetto GCC.

Riepilogo

In questo articolo introduttivo abbiamo descritto brevemente lo sviluppo di videogame Android e l'ottimizzazione nelle piattaforme basate sull'architettura Intel. I motori per videogame sono la parte centrale di tutto lo sviluppo dei videogame. Se i motori funzionano bene sulle piattaforme basate sull'architettura Intel, allora anche i videogame funzioneranno bene. Abbiamo preso come esempio cocos2dx, un motore di gioco tra i più diffusi, per dimostrare come sviluppare sulla piattaforma basata sull'architettura Intel. Intel offre inoltre molti strumenti per sviluppatori con cui ottimizzare le applicazioni videogame sulle piattaforme Android. Nell'uso di Intel System Studio abbiamo mostrato i passi di come ottimizzare un'applicazione dimostrativa.

Informazioni sull'autore

Tao Peng è un ingegnere informatico del gruppo software e servizi presso Intel che si occupa specificatamente dell'abilitazione delle applicazioni mobili, incluso lo sviluppo di applicazioni Android e la loro ottimizzazione per i dispositivi x86 e lo sviluppo di applicazioni Web HTML5.

Cosa c'è di nuovo? Intel® Threading Building Blocks 4.2

$
0
0

Una delle librerie più conosciute di threading C++, Intel ® Threading Building Blocks (Intel® TBB), è stata recentemente aggiornata a una nuova versione, la 4.2. Rispetto alla precedente versione 4.1, la versione aggiornata contiene diverse nuove importanti funzionalità, alcune delle quali erano già state rilasciate negli aggiornamenti di Intel TBB 4.1.

La nuova primitiva di sincronizzazione speculative_spin_mutex introduce il supporto per il blocco speculativo. Ciò è reso possibile usando la funzione hardware Intel® Transactional Synchronization Extensions (Intel® TSX) disponibile nei processori Intel® Core™ di quarta generazione. Sui processori che supportano la memoria transazionale hardware (come Intel® TSX), i mutex speculativi lasciano che più thread acquisiscano lo stesso blocco, a condizione che non ci siano "conflitti" che possono generare risultati diversi rispetto al blocco non speculativo. Quindi la serializzazione non avviene nei casi non contesi. Ciò consente di migliorare significativamente le prestazioni e la scalabilità di "brevi" sezioni critiche. Se il supporto hardware per la sincronizzazione transazionale non è presente, i mutex speculativi si comportano come le loro controparti non speculative, ma probabilmente con prestazioni peggiori.

Intel TBB supporta ora la funzione di propagazione esatta delle eccezioni (basata su C++11 exception_ptr). Con exception_ptr, gli oggetti eccezione possono essere copiati in modo sicuro tra i thread. In questo modo viene introdotta flessibilità nella gestione delle eccezioni in un ambiente multithreading. La propagazione esatta delle eccezioni è disponibile in file binari precompilati per tutte le piattaforme: OS X*, Windows* e Linux*. In OS X ci sono due gruppi di binari: il primo, che è collegato con la libreria standard gcc, è utilizzato per impostazione predefinita e non supporta la propagazione esatta delle eccezioni. Per utilizzare la funzione, si deve prendere il secondo gruppo di binari collegati con libc++, la libreria C++ standard in Clang. Per utilizzarli, impostare l'ambiente di Intel TBB e compilare l'applicazione nel modo seguente:

     # tbbvars.sh libc++
     # clang++ -stdlib=libc++ -std=c++11 concurrent_code.cpp -ltbb

Oltre ai contenitori concurrent_unordered_set e concurrent_unordered_map, ora forniamo concurrent_unordered_multiset e concurrent_unordered_multimap basati sul prototipo Microsoft* PPL. concurrent_unordered_multiset offre la possibilità di inserire un elemento più di una volta, cosa non possibile in concurrent_unordered_set. Allo stesso modo, concurrent_unordered_multimap permette di inserire più di una coppia <chiave,valore> con lo stesso valore di chiave. Per entrambi i "multi" contenitori find restituirà la prima voce (o coppia <chiave,valore>) nella tabella con una chiave di ricerca corrispondente.

I contenitori Intel TBB ora possono essere comodamente inizializzati con gli elenchi di valori specificati da C++ 11 (elenchi di inizializzatori):

tbb::concurrent_vector<int> v ({1,2,3,4,5} );

Attualmente gli elenchi di inizializzazione sono supportati dai seguenti contenitori:

concurrent_vector
concurrent_hash_map
concurrent_unordered_set
concurrent_unordered_multiset
concurrent_unordered_map
concurrent_unordered_multimap
concurrent_priority_queue

L'allocatore di memoria scalabile ha cache di memoria allocata in ogni thread. Ciò viene fatto per motivi di prestazioni, ma spesso a costo di un maggiore utilizzo della memoria. Anche se l'allocatore di memoria fa il possibile per evitare un utilizzo eccessivo della memoria, nei casi complessi Intel TBB 4.2 dà più controllo al programmatore: è ora possibile ridurre il consumo di memoria pulendo le cache dei thread con la funzione scalable_allocation_command(). Erano anche presenti diversi miglioramenti nelle prestazioni complessive dell'allocatore.

La libreria Intel TBB è ampiamente utilizzata su diverse piattaforme. Gli sviluppatori di applicazioni mobili possono ora trovare i file binari precompilati per Android nel pacchetto del sistema operativo Linux. I file binari per le applicazioni Windows Store sono stati aggiunti al pacchetto del sistema operativo Windows.

Le variabili atomiche tbb::atomic<T> hanno ora i costruttori se usate in C++11. Ciò consente ai programmatori di inizializzare il loro valore al momento della dichiarazione, con le espressioni const adeguatamente supportate. Attualmente questo funziona per i compilatori gcc e Clang:

tbb::atomic<int> v=5;

La nuova funzione Community Preview consente l'attesa fino a quando tutti i thread di lavoro terminano. Questo potrebbe essere necessario se un'applicazione biforca i processi o se la libreria dinamica Intel TBB può essere scaricata in fase di esecuzione (ad esempio, se Intel TBB fa parte di un plugin). Per attivare l'attesa dei thread di lavoro, inizializzare l'oggetto task_scheduler_init in questo modo:

#define TBB_PREVIEW_WAITING_FOR_WORKERS 1
tbb::task_scheduler_init scheduler_obj (threads, 0, /*wait_workers=*/true);

Potete trovare il nuovo Intel TBB 4.2 nei siti commerciali e open source. Scaricate e divertitevi con la nuova funzionalità!

Compilare applicazioni Android* NDK con Intel® Integrated Performance Primitives (Intel® IPP)

$
0
0


Intel® Integrated Performance Primitives (Intel® IPP) fornisce delle funzioni di elementi di base altamente ottimizzate per l'elaborazione delle immagini, l'elaborazione del segnale, la matematica vettoriale e il calcolo di matrici ridotte. Diversi domini di Intel IPP contengono le funzioni manualmente ottimizzate per il processore Intel® Atom™ utilizzando le istruzioni di Intel® Streaming SIMD Extensions (Intel® SSE). Le librerie Linux* statiche e non-threaded di Intel IPP ora supportano il sistema operativo Android* e possono essere utilizzate con le applicazioni Android.

Questo articolo fornisce un'introduzione su come aggiungere funzioni Intel IPP nelle applicazioni Android NDK. Intel IPP offre un'ottimizzazione specifica del processore e può essere collegato solo con codice C/C++ nativo Android. Per utilizzare Intel IPP con l'applicazione, è necessario includere nel codice sorgente le funzioni di Intel IPP ed è inoltre necessario aggiungere le librerie Intel IPP nella riga di comando di compilazione.

Uso di Intel IPP

1. Aggiunta delle funzioni di Intel IPP nella sorgente

  • Includere i file di intestazione di Intel IPP (ipp.h) nei file sorgente.
  • Chiamare ippInit() prima di utilizzare qualsiasi altra funzione Intel IPP. Intel IPP rileva le caratteristiche del processore e seleziona il percorso di ottimizzazione del codice per i processori di destinazione. Prima di chiamare altre funzioni di Intel IPP, chiamare ippInit() per inizializzare il dispatching della CPU per Intel IPP.
  • Chiamare le funzioni Intel IPP nella sorgente C/C++.

2. Inclusione delle librerie Intel IPP nei file di compilazione Android NDK

  • Copiare le librerie e le intestazioni di Intel IPP nella cartella del progetto.
  • Individuare le librerie Intel richieste per l'applicazione: le librerie Intel IPP sono suddivise in diversi domini. Ogni dominio ha una propria libreria e alcune librerie di dominio dipendono da altre. È necessario che tutte le librerie di dominio e le loro dipendenze siano incluse nella riga di collegamento. Consultare l'articolo sulle “Dipendenze della libreria Intel IPP” per informazioni sulle librerie Intel IPP necessarie.
  • Aggiungere le librerie Intel IPP al file di script di compilazione Android “jni/Android.mk”:
    Dichiarare ogni libreria Intel IPP come modulo di libreria precompilato. Ad esempio, se l'applicazione utilizza due librerie Intel IPP "libipps.a" e "libippcore.a", aggiungere al file quanto segue:
               include $(CLEAR_VARS)
               LOCAL_MODULE := ipps
               LOCAL_SRC_FILES := ../ipp/lib/ia32/libipps.a
               include $(PREBUILT_STATIC_LIBRARY)

               include $(CLEAR_VARS)
               LOCAL_MODULE := ippcore
               LOCAL_SRC_FILES := ../ipp/lib/ia32/libippcore.a
               include $(PREBUILT_STATIC_LIBRARY) 

Aggiungere il percorso dell'intestazione e le librerie Intel IPP nei moduli di chiamata delle funzioni Intel IPP:

               include $(CLEAR_VARS)
               LOCAL_MODULE := IppAdd
               LOCAL_SRC_FILES := IppAdd.c
               LOCAL_STATIC_LIBRARIES := ipps ippcore
               LOCAL_C_INCLUDES := ./ipp/include
               include $(BUILT_SHARED_LIBRARY)

Compilazione di un esempio di codice

Qui di seguito è riportato un semplice esempio che mostra l'utilizzo di Intel IPP nel codice nativo Android. Il codice utilizza la funzione Intel IPP ippsAdd_32f() per aggiungere i dati per due array.

Per rivedere l'utilizzo di Intel IPP nel codice:

  1. Scaricare il codice di esempio e scompattarlo nella cartella del progetto (<directoryprogetto>).
  2. Imparare l'utilizzo di Intel IPP nei file sorgente: il file "jni/IppAdd.c" fornisce l'implementazione di una funzione nativa NativeIppAdd (). La funzione chiama la funzione Intel IPP ippsAdd_32f(). Il file "src/com/example/testippadd/ArrayAddActivity.java" chiama la funzione nativa "NativeIppAdd()" tramite JNI.
  3. Controllare il file "jni/Android.mk". Questo file aggiunge le necessarie librerie Intel IPP allo script di compilazione. L'esempio utilizza la funzione ippsAdd_32f() che appartiene al dominio di elaborazione del segnale Intel IPP. La funzione dipende dalle librerie "libipps.a" e "libippcore.a". Il file "Android.mk" crea per loro due librerie precompilate.

È possibile creare il codice di esempio sia utilizzando gli strumenti di comando dell'SDK e dell'NDK che utilizzando Eclipse* IDE

Compilare l'esempio dalla riga di comando

>cd <projectdir>
         ><ndkdir>/ndk-build 
>cd <projectdir>
         >android update project -p . -s
         >ant debug
         >adb install bin/ArrayAddActivity-debug.apk 
  1. Copiare le intestazioni e librerie Intel IPP nella cartella del progetto (ad esempio <directoryprogetto>/ipp).
  2. Eseguire lo script "ndk-build" dalla directory del progetto per compilare il codice nativo
  3. Compilare il pacchetto Android e installare l'applicazione

Compilare l'esempio da Eclipse* IDE

>cd <projectdir>
         ><ndkdir>/ndk-build 
  1. Copiare le intestazioni e le librerie Intel IPP nella cartella del progetto (ad esempio <directoryprogetto>/ipp).
  2. In Eclipse, fare clic su File (File)>> New (Nuovo)>> Project... (Progetto)>> Android (Android)>> Android Project from Existing Code (Progetto android da codice esistente). In "Root Directory" (Directory principale), selezionare la cartella del codice di esempio, quindi fare clic su Finish (Fine).
  3. Eseguire lo script 'ndk-build' dalla directory del progetto per compilare il codice nativo:
  4. Compilare l'applicazione in Eclipse IDE e distribuire il file .apk.

Riepilogo
Questo articolo fornisce un'introduzione all'uso di Intel IPP con le applicazioni native Android. Per ulteriori informazioni sulle funzioni di Intel IPP, consultare il manuale di Intel IPP.

Strumenti di Intel® HTML5 per lo sviluppo di applicazioni mobili

$
0
0

di Egor Churaev

Download


Strumenti di Intel® HTML5 per lo sviluppo di applicazioni mobili [PDF 821.98 KB]
Codice sorgente iOS [file ZIP da 168 KB]
Codice sorgente dei risultati degli strumenti HTML5 [file ZIP da 86 KB]

HTML5 è il nuovo standard HTML. Intel Corporation ha recentemente annunciato una serie di strumenti HTML5 per lo sviluppo di applicazioni mobili. Questo documento mostra come effettuare il porting di un'applicazione accelerometro Apple iOS* verso HTML5 utilizzando questi strumenti. Notare che il codice generato automaticamente da Intel® XDK potrebbe contenere del codice concesso in licenza in base alle licenze descritte nell'Appendice A del presente documento. Fare riferimento all'output di Intel XDK per sapere quali librerie sono utilizzate per abilitare l'applicazione.

Intel® HTML5 App Porter Tool


La prima cosa che faremo è prendere l'applicazione iOS dell'accelerometro e convertire in HTML5 il codice sorgente Objective-C*. Lo faremo utilizzando lo strumento Intel® HTML5 App Porter Tool e il codice sorgente che si trova qui: [iOS_source.zip] (notare che il codice di esempio IOS_source viene fornito sotto la Licenza del codice sorgente di esempio Intel descritta nell'Appendice B).È possibile scaricare Intel HTML5 App Porter Tool dalla scheda Tools all'indirizzo http://software.intel.com/it-it/html5. Dopo aver compilato e inviato il modulo con il proprio indirizzo e-mail, si otterranno i link per scaricare questo strumento. Le istruzioni su come utilizzare lo strumento possono essere trovati nel sito http://software.intel.com/it-it/articles/tutorial-creating-an-html5-app-from-a-native-ios-project-with-intel-html5-app-porter-tool

Terminata l'esecuzione di tutti i passaggi, si otterrà il codice sorgente HTML5.

Intel XDK


Il codice HTML5 può essere aperto in qualsiasi IDE. Intel offre un comodo strumento per lo sviluppo di applicazioni HTML5, l'Intel XDK - Kit di sviluppo per più piattaforme (http://software.intel.com/it-it/html5/tools). Con Intel XDK, gli sviluppatori possono scrivere un codice sorgente unico da distribuire su molti dispositivi. Ciò che è particolarmente comodo è che non è necessario installarlo sul proprio computer. È possibile installarlo come un'estensione di Google Chrome*. Se si utilizza un altro browser, è necessario scaricare un file JavaScript* ed eseguirlo. A volte è necessario aggiornare Java*.

Dopo aver installato Intel XDK, viene visualizzata la finestra principale:

Se si desidera eseguire il porting del codice esistente, premere il grosso pulsante "Start new".

Se si sta creando un nuovo progetto, immettere il nome del progetto e selezionare “Create your own from scratch”, come mostrato nella schermata qui sotto.

Selezionare “Use a blank project”. Attendere finché appare il messaggio “Application Created Successfully!”

Fare clic su “Open project folder”.

Rimuovere tutti i file da questa cartella e copiare i file di cui si è eseguito il porting. Il porting dell'applicazione accelerometro non è però ancora avvenuto. Si deve ancora a scrivere un'interfaccia per l'applicazione. È possibile rimuovere gli hook creati da Intel HTML5 App Porter Tool. Rimuovere questi file:

  • todo_api_application__uiaccelerometerdelegate.js
  • todo_api_application_uiacceleration.js
  • todo_api_application_uiaccelerometer.js
  • todo_api_js_c_global.js

Per aggiornare il progetto in Intel XDK, andare alla finestra dell'editor nell'emulatore di Windows.

Aprire il file index.html e rimuovere le righe lasciate dai file inclusi.

Aprire il file todo_api_application_appdelegate.js e implementare la proprietà “window” non mappata del delegato.

application.AppDelegate.prototype.setWindow = function(arg1) {
    // ================================================================
    // REFERENCES TO THIS FUNCTION:
    // line(17): C:WorkBloggingechuraevAccelerometerAccelerometerAppDelegate.m
    //    In scope: AppDelegate.application_didFinishLaunchingWithOptions
    //    Actual arguments types: [*js.APT.View]
    //    Expected return type: [unknown type]
    //
    //if (APT.Global.THROW_IF_NOT_IMPLEMENTED)
    //{
        // TODO remove exception handling when implementing this method
       // throw "Not implemented function: application.AppDelegate.setWindow";
    //}
this._window = arg1;
};

application.AppDelegate.prototype.window = function() {
    // ================================================================
    // REFERENCES TO THIS FUNCTION:
    // line(20): C:WorkBloggingechuraevAccelerometerAccelerometerAppDelegate.m
    //    In scope: AppDelegate.application_didFinishLaunchingWithOptions
    //    Actual arguments types: none
    //    Expected return type: [unknown type]
    //
    // line(21): C:WorkBloggingechuraevAccelerometerAccelerometerAppDelegate.m
    //    In scope: AppDelegate.application_didFinishLaunchingWithOptions
    //    Actual arguments types: none
    //    Expected return type: [unknown type]
    //
    //if (APT.Global.THROW_IF_NOT_IMPLEMENTED)
    //{
        // TODO remove exception handling when implementing this method
       // throw "Not implemented function: application.AppDelegate.window";
    //}
return this._window;
};

Aprire il file viewcontroller.js. Rimuovere tutte le funzioni utilizzate per lavorare con l'accelerometro nella vecchia applicazione iOS. Alla fine si ottiene questo file:

APT.createNamespace("application");

document.addEventListener("appMobi.device.ready",onDeviceReady,false);

APT.ViewController = Class.$define("APT.ViewController");

application.ViewController = Class.$define("application.ViewController", APT.ViewController, {
    __init__: function() {
        this.$super();
    };>});

Nel file ViewController_View_774585933.css dobbiamo cambiare gli stili dei colori degli elementi da nero a bianco in modo che siano leggibili su sfondo nero: da color: rgba(0,0,0,1); a color: rgba(256,256,256,1);. Come risultato si ottiene:

div#Label_590244915
{
	left: 20px;
	color: rgba(256,256,256,1);
	height: 21px;
	position: absolute;
	text-align: left;
	width: 320px;
	top: 0px;
	opacity: 1;
}
div#Label_781338720
{
	left: 20px;
	color: rgba(256,256,256,1);
	height: 21px;
	position: absolute;
	text-align: left;
	width: 42px;
	top: 29px;
	opacity: 1;
}
div#Label_463949782
{
	left: 20px;
	color: rgba(256,256,256,1);
	height: 21px;
	position: absolute;
	text-align: left;
	width: 42px;
	top: 51px;
	opacity: 1;
}
div#Label_817497855
{
	left: 20px;
	color: rgba(256,256,256,1);
	height: 21px;
	position: absolute;
	text-align: left;
	width: 42px;
	top: 74px;
	opacity: 1;
}
div#Label_705687206
{
	left: 70px;
	color: rgba(256,256,256,1);
	height: 21px;
	position: absolute;
	text-align: left;
	width: 42px;
	top: 29px;
	opacity: 1;
}
div#Label_782673145
{
	left: 70px;
	color: rgba(256,256,256,1);
	height: 21px;
	position: absolute;
	text-align: left;
	width: 42px;
	top: 51px;
	opacity: 1;
}
div#Label_1067317462
{
	left: 70px;
	color: rgba(256,256,256,1);
	height: 21px;
	position: absolute;
	text-align: left;
	width: 42px;
	top: 74px;
	opacity: 1;
}
div#View_774585933
{
	left: 0px;
	height: 548px;
	position: absolute;
	width: 320px;
	top: 20px;
	opacity: 1;
}

Dopo aver aggiornato la finestra dell'emulatore, si vede:

 

Per codificare le funzioni dell'accelerometro bisogna usare appMobi JavaScript Library. La documentazione di questa libreria può essere trovata qui. È installata quando si scarica Intel XDK.

Aprire il file index.html e aggiungere questa riga all'elenco degli script:

<script type="text/javascript" charset="utf-8" src="http://localhost:58888/_appMobi/appmobi.js"></script>

Aprire il file ViewController_View_774585933.html. Dobbiamo rinominare i campi con nomi più logici, cioè da:

<div data-apt-class="Label" id="Label_705687206">0</div>
<div data-apt-class="Label" id="Label_782673145">0</div>
<div data-apt-class="Label" id="Label_1067317462">0</div>

a:

<div data-apt-class="Label" id="accel_x">0</div>
<div data-apt-class="Label" id="accel_y">0</div>
<div data-apt-class="Label" id="accel_z">0</div>

Lo stesso dovrebbe essere fatto nel file ViewController_View_774585933.css, dove dobbiamo rinominare i nomi degli stili.

Aprire il file viewcontroller.js e scrivere alcune funzioni per utilizzare l'accelerometro.

function suc(a) {
    document.getElementById('accel_x').innerHTML = a.x;
    document.getElementById('accel_y').innerHTML = a.y;
    document.getElementById('accel_z').innerHTML = a.z;
}

var watchAccel = function () {
    var opt = {};
    opt.frequency = 5;
    timer = AppMobi.accelerometer.watchAcceleration(suc, opt);
}

function onDeviceReady() {
    watchAccel();
}
document.addEventListener("appMobi.device.ready",onDeviceReady,false);

Aggiornare il progetto. Lo si può vedere sulla finestra di emulazione:

È possibile vedere come funziona l'accelerometro in Intel XDK utilizzando il pannello “ACCELEROMETER”:

L'applicazione sarà simile a questa:

Il codice sorgente completo dell'applicazione è reperibile qui.
Appendice A: Contratti di licenza del codice Intel® XDK

Appendice B: Contratto di licenza del codice sorgente di esempio Intel

 

Intel e il logo Intel sono marchi di Intel Corporation registrati negli Stati Uniti e/o in altri paesi.
 Copyright © 2013 Intel Corporation. Tutti i diritti riservati.
*Altri marchi e denominazioni potrebbero essere proprietà di terzi.


Servizi per testare le applicazioni Android su dispositivi Intel

$
0
0

Sempre più dispositivi Android hanno Intel Inside. Oltre a procurarvi dispositivi Android basati su Intel per testare le applicazioni e assicurare che offrano agli utenti l'esperienza migliore, potete accedere a servizi che consentono di testare le applicazioni su svariato hardware senza dover acquisire e mantenere un gran numero di dispositivi fisici. Questi sono alcuni servizi che consigliamo.

AppThwack

AppThwack vi consente di testare le applicazioni su centinaia di dispositivi fisici reali in un ambiente di laboratorio. Caricate il codice, eseguite i test e create un report così potete risolvere gli eventuali problemi prima che li scoprano gli utenti. Grazie all'Intel® Developer Zone potete accedere a AppThwack per un periodo di tempo limitato ed eseguire gratuitamente test sui dispositivi Android basati su Intel. Potete trovare maggiori informazioni nella nostra guida alle procedure e iniziare a utilizzare appthwack.com.

Applause

La community globale Applause di professionisti nel campo dell'assicurazione qualità aiuta ad assicurare che le applicazioni Android siano eseguite sui dispositivi basati su Intel degli utenti allo stesso modo di come lo sono in laboratorio. Potete testare nei luoghi sperduti in cui si trovano gli utenti per assicurare che la vostra applicazione Android sia testata sui dispositivi Intel e ARM usando molteplici browser, gestori telefonici e posizioni geografiche. Per maggiori informazioni e per iniziare, visitare il sito Web applause.com.

Java vs C vs IPP vs TBB: test di performance su dispositivi Intel

$
0
0

Di recente ci siamo trovati nella situazione di voler ottimizzare una nostra applicazione per la realta’ aumentata (http://picshare.jooink.com) su dispositivi mobile. Picshare e' interamente scritto in javascript ed essendo il nostro target quello di ottimizzarlo per dispositivi mobile la strada più naturale ci è sembrata quella di riscrivere nativamente parte degli algoritmi computazionalmente rilevanti e, con l’occasione, mettere a confronto diverse implementazioni ‘native’ al fine di capire quale strategia fosse preferibile.

Sfruttando il fatto che da sempre Intel mette a disposizione numerose librerie ottimizzate per i suoi processori e che adesso sono disponibili dispositivi mobile con processori intel abbiamo voluto capire anche quanto l’utilizzo di librerie ottimizzate per una specifica architettura potesse aumentare le performance.

In questo post mostreremo i risultati ottenuti implementando il medesimo algoritmo con ‘tecniche’ (linguaggi e libererie) diverse: java, C, C utilizzando le Intel Performance Primitives, C utilizzando le IPP e parallelizzando l’esecuzione utilizzando Intel Threading Building Blocks.

Tutti i test sono stati effettuatu su 3 dispositivi con processore Intel:

  • Samsung Galaxy Tab 3, tablet 10’’, Intel Atom Z2560, Dual-core
  • Dell Venue 8/3830, tablet 8’’, Intel Atom Z2580, Dual-core
  • Lenovo k900, mobile 5’’, Intel Atom Z2580, Dual-core

Relative performance results

L’algoritmo:

Non potendo certamente riscrivere l’intera applicazione 4 volte abbiamo ritenuto opportuno fare il confronto su un algoritmo semplice da implementare ma computazionalmente rilevante per il nostro caso d’uso.

La maggior parte degli algoritmi utilizzati nelle nostre applicazioni opera su immagini in toni di grigio e la conversione da rgb a grayscale è quindi un candidato ideale per i test; abbiamo quindi deciso di implementare con le diverse ‘tecniche’ il calcolo di una media pesata da un array 3*SIZE a un array SIZE:

gray ← 0.299  * red + 0.587 * green + 0.114 * blue

Allo scopo di minimizzare le complicazioni implementative abbiamo scritto l’algritmo di media in modo che operi su float.

Java version

L’implementazione in java dell’algoritmo di conversione è naturalmente estremamente semplice:

public void compute(float[] in, float[] out) {
    for(int i=0, j=0; i<out.length; i++, j+=3)
       out[i] = 0.299f * in[j] + 0.587f * in[j+1] + 0.114f * in[j+2];
}

Per eseguire ripetutamente la trasformazione (in maniera tutto sommato simile a come facciamo nel codice javascript attualmente utilizzato in produzione), abbiamo inserito le chiamate al metodo ‘compute’ in un AsyncTask che a sua volta viene creato ed eseguito da un Timer ma al fine di evitare che la creazione degli async task ed il timer falsassero i nostri test, abbiamo deciso di effettuare le misurazioni del tempo di esecuzione all’interno dell’async task stesso:

    ...
    long st = System.nanoTime();
    compute(in,out);
    long et = System.nanoTime();
    ...

La pressione sul gargbage collector è mantenuta bassa riutilizzando per tutte le iterazioni i medesimi array di input ed output (2 array bidimensionali di float uno di dimensione 3*1024*1024, interpretati come valori rgb, l’altro 1024*1024, interpretati come valori di una immaginaria scala di grigi).

Come si vede nella figura seguente, sui dispositivi che avevamo a disposizione la performance di questa prima implementazione è assolutamente soddisfacente ed in tutti i casi superiore ai 100Hz.

Absolute performance results

Native C

Fatta l’implementazione in java ci siamo concentrati su quella ‘nativa’ (in C).

L’implementazione nativa richiede l’istallazione del Native Development Kit (NDK).

Seguendo la documentazione che si trova su Android NDK for Intel Architecture, si capisce rapidamente che scrivere una applicazione android/ndk non è in linea di principio complicato (a patto di conoscere il C o il C++ naturalmente) ma, come sempre, il setup del progetto è la cosa che richiede più tempo.

Il setup del primo progetto con ndk è documentato completamente su Creating and Porting NDK based Android Apps for ia, ma se non volete perderci tempo in questo momento ne abbiamo predisposto uno pronto per l’uso su github github.com/jooink/ndk-cpuid.

Clonato il repo per compilarlo ed usarlo non avete da fare altro che

  • entrare nella directory CPUIDApp/jni folder ed eseguire  "ndk-build";
  • tornare nella root directory (CPUIDApp) ed eseguire "ant debug";
  • installare l’applicazione e provare su un dispositivo "adb install -r bin/CPUIdApp-debug.apk".

Per cimentarsi nello sviluppo di applicazioni ndk è indispensabile, oltre a comprendere bene la struttura del progetto e l’uso di ‘ndk-build’, una certa pratica con jni (Java Native Interface) e javah (C Header and Stub File Generator) in quanto ci troviamo nella situazione di voler chiamare codice C da java e quindi jni è sostanzialmente l’unica strada.

Il codice C, fatta eccezione per le ‘stranezze’ dovute appunto a JNI, è sostanzialmente identico a quello in java:

#include <stdlib.h>
#include <math.h>

#include "com..ToGrayscaleTaskNDK.h"

JNIEXPORT void JNICALL
Java_com...ToGrayscaleTaskNDK_grayscale(
JNIEnv *env, jclass c, jfloatArray in,  jfloatArray out) {

  jsize len_in = (*env)->GetArrayLength(env, in);
  jsize len_out = (*env)->GetArrayLength(env, out);

  jfloat *body_in = (*env)->GetFloatArrayElements(env, in, 0);
  jfloat *body_out = (*env)->GetFloatArrayElements(env, out, 0);

  int i,j;
  for(i=0, j=0; i< len_out; i++, j+=3)
    body_out[i] =
         0.299f * body_in[j] +
                 0.587f * body_in[j+1] +
                           0.114f * body_in[j+2];


  (*env)->ReleaseFloatArrayElements(env, in, body_in, 0);
  (*env)->ReleaseFloatArrayElements(env, out, body_out, 0);

  return;
}

Il codice, come spiegato ad esempio su Creating and Porting NDK based Android Apps for ia, deve essere inserito in un file collocato nella directory jni del progetto e compilato con ndk-build dopo aver predisposto il file Andoid.ndk e quello Application.mk dei quali potete trovare una copia sempre facendo riferimento al progetto d’esempio su github.

Il passaggio da Java a C regala all’algoritmo una crescita della performance dell’ordine del 35% su tutti i dispositivi in esame.


Native C/IPP

Per guadagnare ancora performance non abbiamo altra strada a questo punto che cercare sfruttare meglio l’hardware dei dispositivi abbandonando la strada della portabilità e utilizzando librerie ‘specifiche’ per i processori utilizzati.

Fino ad ora il codice che abbiamo scritto  era interamente portabile ed era quindi possibile eseguire l’applicazione su qualsiasi piattaforma. In quello che aggiungeremo a partire da questa sezione  utilizzeremo invece librerie specifiche per intel ed anche solo per testare l’applicazione durante lo sviluppo è assai più comodo utilizzare anche un emulatore basato su processore x86.
Dunque, se sviluppate su una macchina con processore intel, consigliamo di scaricare ed installare l’emulatore x86 e HAXM, l’acceleratore che rende estremamente più rapido l’emulatore e quindi più piacevole la vita degli sviluppatori (per dettagli si veda ad esempio HAXM speeds up the Android emulator).
Naturalmente benché l’emulatore x86 con HAXM sia uno strumento molto comodo per lo sviluppo, non ci possiamo aspettare di poter fare analisi di performance  usando l’emulatore e quindi un dispositivo ‘vero’ è indispensabile.


Preparato l’ambiente di sviluppo per programmare x86 e fatto il setup per l’ndk siamo a pronti per utilizzare le librerie Intel ottimizzate per Android. 

Le Intel PP sono una collezione di librerie per “multimedia processing, data processing, communications applications” per Windows, Linux, Android, and OS X, tra le quali troviamo anche una versione ottimizzata dell’algoritmo di trasformazione da RGB a grayscale che ci permette di capire quanto il nostro codice ‘vanilla’ possa trarre vantaggio da una implementazione dedicata ad una precisa architettura.

La preview delle IPP per Android è inclusa in Beacon Mountain e su Building Android NDK Applications with Intel IPP viene descritto in modo dettagliato come fare il setup di un progetto che le utilizzi.

Il problema a questo punto pero’ è che che le IPP in Beacon Mountain sono davvero solo una ‘preview’: uno scheletro delle librerie in cui sono implementati solo un paio di metodi. Servono per provare che funzionano, non per usarle e di sicuro nemmeno  per fare i nostri test.

Per avere una versione utilizzabile delle IPP occorre scaricare ed installare la versione trial per Linux (che è utilizzabile per 30 giorni, dopo bisogna acquistare quella commerciale); se come noi sviluppate su OSX la cosa davvero più facile è farsi una macchina virtuale Linux e usare quella per procedere all’istallazione.
Una volta installate le librerie sulla macchina Linux è sufficiente copiare gli include file da /opt/intel/ipp/include le librerie a 32 bit da /opt/intel/ipp/lib/ia32.
IPP è divisa in diversi moduli ma per le funzioni di “image conversion” basta copiare libippcore.a libippcc.a, mentre gli header tanto vale copiarli tutti.
Noi abbiamo messo sia le librerie che gli include  direttamente dentro la directory jni.

Fatte le copie è il momento di preparare l’opportuno Android.mk che faccia riferimento alle librerie statiche e provveda al linking corretto:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := grayscale
LOCAL_STATIC_LIBRARIES := libippcc ippcore
LOCAL_C_INCLUDES := .
LOCAL_LDLIBS := -llog  -lc -landroid -lm -ljnigraphics
LOCAL_SRC_FILES := com_jooink_experiments_android_preformance_java_ToGrayscaleTaskNDK.c com_jooink_experiments_android_preformance_java_ToGrayscaleTaskIPP.c
include $(BUILD_SHARED_LIBRARY)

 

include $(CLEAR_VARS)
LOCAL_MODULE    := ippcore
LOCAL_SRC_FILES := libippcore.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := ippcc
LOCAL_SRC_FILES := libippcc.a
include $(PREBUILT_STATIC_LIBRARY)

Si osserva che le 2 librerie sono citate sia nei 2 blocchi PREBUILT_STATIC_LIBRARY che nella variabile LOCAL_STATIC_LIBRARIES.

Il codice per la conversione in grayscale utilizzando IPP è quasi più semplice di quello scritto direttamente in C:

#include <stdlib.h>
#include <math.h>
#include <jni.h>
#include "ipp.h"

#include "com_jooink_experiments_android_preformance_java_ToGrayscaleTaskIPP.h"

JNIEXPORT void JNICALL Java_com_jooink_experiments_android_preformance_java_ToGrayscaleTaskIPP_grayscaleIPP(JNIEnv *env, jclass c, jfloatArray in,  jfloatArray out) {


  jsize len_in = (*env)->GetArrayLength(env, in);
  jsize len_out = (*env)->GetArrayLength(env, out);

  jfloat *body_in = (*env)->GetFloatArrayElements(env, in, 0);
  jfloat *body_out = (*env)->GetFloatArrayElements(env, out, 0);

  IppiSize srcRoi = { 1024, 1024 };
  Ipp32f* pSrc = (jfloat*)body_in;
  Ipp32f* pDst = (jfloat*)body_out;
  ippiRGBToGray_32f_C3C1R(pSrc ,1024*4*3, pDst, 1024*4, srcRoi);

  (*env)->ReleaseFloatArrayElements(env, in, body_in, 0);
  (*env)->ReleaseFloatArrayElements(env, out, body_out, 0);

  return;
}

che è sostanzialmente identica alla versione in C tranne per le righe in cui si effettua la chiamata a  ippiRGBToGray_32f_C3C1R che opera la conversione.

Dopo aver messo, come al solito, il codice nella directory jni ed averlo compilato (ndk-build) possiamo generare l’apk (ad esempio attraverso eclipse).
Installiamolo sull’emulatore (adb install …) o su un dispositivo con processore Intel ed eseguiamolo.

Sull’emulatore questa volta nei nostri test si guadagna oltre un ordine di grandezza ma la cosa è meno interessante del fatto che consistentemente su tutti i dispositivi abbiamo un incremento del 20-25% !  visto che l’algoritmo è banale ci viene tutto sommato da domandarsi come sia fatta l’implementazione e quanto sia possibile guadagnare utilizzando gli algoritmi più sofisticati che si trovano in IPP.


Native C/IPP/TBB

Resta da capire a questo punto se con il solo utilizzo delle librerie IPP la nostra ricerca di performance debba considerarsi conclusa. Tra tutte le questioni quella che ci premeva di più capire era se effettivamente stessimo utilizzando tutti i core dei processori.

Per la verità leggendo le Release Notes si scopre, con nostro dolore, che le Performance Primitives da qualche versione hanno deprecato la gestione della parallelizzazione degli algoritmi su processori multicore e quindi si ‘limitano’ a fornire algoritmi ottimizzati per ogni singolo core lasciando agli sviluppatori il compito di trovare la giusta strategia di parallelizzazione.

Il perché di questa scelta risulta più chiaro se  si osserva che nel vasto parco di librerie che Intel mette a disposizione ce ne è una dal nome Threading Building Blocks (Intel TBB) che specificatamente mira a fornire le primitive per la parallelizzazione multithread degli algoritmi.

La compilazione ed installazione di TBB esula dallo scopo di questo post ma è interessante osservare che TBB e IPP sembrano fatte apposta per essere usate insieme ed infatti è banale estendere l’algoritmo per diventare parallelo:

JNIEXPORT void JNICALL Java_com...grayscaleIPPTBB
(JNIEnv *env, jclass c, jfloatArray in,  jfloatArray out) {

  jsize len_in = env->GetArrayLength(in);
  jsize len_out = env->GetArrayLength(out);

  jfloat *body_in = env->GetFloatArrayElements(in, 0);
  jfloat *body_out = env->GetFloatArrayElements(out, 0);

  Ipp32f* pSrc = (jfloat*)body_in;
  Ipp32f* pDst = (jfloat*)body_out;

  tbb::parallel_invoke(
          [pSrc,pDst] {
                  IppiSize srcRoi = { 1024, 512 };
                  ippiRGBToGray_32f_C3C1R(pSrc ,1024*4*3, pDst, 1024*4, srcRoi);
              },
              [pSrc,pDst] {
                  IppiSize srcRoi = { 1024, 512 };
                  Ipp32f* pSrcShifted = pSrc+3*(1024*512);
                  Ipp32f* pDstShifted = pDst+(1024*512);
                  ippiRGBToGray_32f_C3C1R(pSrcShifted ,1024*4*3,
pDstShifted, 1024*4, srcRoi);
              });


  env->ReleaseFloatArrayElements(in, body_in, 0);
  env->ReleaseFloatArrayElements(out, body_out, 0);


  return;
}

dove si vede quanto risulti apprezzabile il fatto che tutti gli algoritmi di IPP che lavorano su array bidimensionali usino il concetto di Regions of Interest permettendoci di splittare in 2 parti (eseguite in parallelo) il calcolo della conversione in grayscale.

Abbiamo provato l’algoritmo parallelo basato su parallel_invoke (probabilmente la primitiva più semplice di TBB) sia usando 2 thread che usandone 4 ed i risultati sono quelli attesi: quasi un fattore 2 tra single thread e dual thread (tutti i dispositivi hanno processori a due core) ed un altro, sorprendente, 25-30% di guadagno passando alla versione a 4 thread.

Vale decisamente la pena di indagare meglio le TBB, partendo magari dai loro sorgenti che sono disponibili a http://www.threadingbuildingblocks.org.

 

Creazione e porting di applicazioni Android* basate su NDK per l'architettura Intel

$
0
0

Obiettivo

Quest'articolo è un'introduzione per principianti sulla creazione di applicazioni native Android* (basate su NDK) per i dispositivi basati sull'architettura Intel®. Tratta anche del porting verso i dispositivi basati sull'architettura Intel di applicazioni NDK Android originariamente create per dispositivi basati su altre architetture. Analizzeremo due scenari, uno per mostrare il processo completo di creazione di una semplice applicazione Android* basata su NDK e l'altro per dimostrare un semplice processo di porting di un'applicazione Android basata su NDK affinché sia utilizzabile su dispositivi basati sull'architettura Intel.

Indice

1. Introduzione

2. Creazione di un'applicazione Android basata su NDK per dispositivi basati sull'architettura Intel - Procedura dettagliata di una semplice applicazione

a. Creare un progetto Android predefinito
b. Richiamare il codice nativo dai file sorgente Java
c. Usare javah per generare gli stub dell'header JNI per il codice nativo
d. Compilare il codice nativo con l'NDK per l'architettura Intel
e. Ricompilare, installare ed eseguire l'applicazione Android NDK per l'architettura Intel

3. Uso degli strumenti dell'NDK x86 per eseguire il porting verso dispositivi basati sull'architettura Intel di applicazioni NDK esistenti

4. Riepilogo

Introduzione

È possibile incorporare codice nativo nelle applicazioni Android usando gli strumenti del Native Development Kit (NDK). Questo permette agli sviluppatori di riusare il codice legacy, codificare per l'hardware di basso livello o differenziare le applicazioni sfruttando funzioni che altrimenti non sarebbero ottimali o disponibili.

Questo articolo è un'introduzione elementare su come creare, dall'inizio alla fine, applicazioni basate su NDK per l'architettura Intel e include anche dei semplici casi di utilizzo per eseguire il porting di applicazioni esistenti basate su NDK verso dispositivi basati sull'architettura Intel. Sarà descritto dettagliatamente un semplice scenario di sviluppo di un'applicazione per dimostrare il processo.

Si presume che l'ambiente di sviluppo Android sia già installato, compresi l'Android SDK, l'Android NDK e l'emulatore x86 configurato per testare le applicazioni. Per ulteriori informazioni, si prega di fare riferimento alla sezione della comunità Android nel sito Web di Intel. Per mantenere un ambiente di sviluppo semplice, nella maggior parte dei casi si useranno strumenti della riga di comando Linux*.

Creazione di un'applicazione Android basata su NDK per dispositivi basati sull'architettura Intel - Procedura dettagliata di una semplice applicazione

Si presuma di avere del codice legacy che usa C e il linguaggio assembly per analizzare l'istruzione CPUID (per maggiori informazioni su CPUID, consultare http://it.wikipedia.org/wiki/CPUID*). Qui di seguito è il listato del file sorgente del nostro codice C “legacy” di esempio cpuid.c (che è solo a scopo dimostrativo).

Desideriamo richiamare cpuid_parse dalla nostra applicazione Android (solo a scopo dimostrativo; la funzione cpuid_parse prevede un buffer preallocato) e visualizzare l'output all'interno dell'applicazione.

Qui di seguito è descritta la procedura dettagliata per creare l'applicazione Android dall'inizio alla fine e usare il codice nativo legacy visto in precedenza.

1. Creare un progetto Android predefinito

Android SDK ha strumenti della riga di comando che consentono di generare una struttura di progetto predefinita per un'applicazione hello world tipica. Creeremo innanzitutto un progetto predefinito, quindi modificheremo i file sorgente Java in modo da poter aggiungere chiamate JNI e codice nativo.

Nella schermata precedente, abbiamo prima creato una directory chiamata labs/lab2 e usato lo strumento della riga di comando “android” per generare il progetto predefinito. Abbiamo specificato android-15 come livello di API e chiamato la nostra applicazione “CPUIdApp” con package com.example.cpuid.

Abbiamo quindi usato lo strumento della riga di comando “ant” per creare il progetto in modalità di debug e installare usando “adb” (o reinstallare se già esistente nell'emulatore e nella destinazione). Si presume che abbiate già un emulatore o un dispositivo collegato e che sia l'unico dispositivo che viene elencato nell'output del comando “adb devices”.

La schermata seguente mostra l'emulatore Android x86 con ICS dopo avere completato il processo precedente.

Facendo clic sull'applicazione, viene visualizzato l'output predefinito hello world dell'applicazione. Modificheremo ora l'applicazione per l'uso del codice nativo.

2. Richiamare il codice nativo dai file sorgente Java

Il progetto Android predefinito genera i file sorgente Java per un progetto hello world tipico con lo spazio dei nomi del pacchetto dato (es. com.example.cpuid). La schermata seguente mostra il codice sorgente generato per il file sorgente Java principale.

Per usare il codice nativo C/C++ nel nostro file sorgente Java, dobbiamo prima dichiarare la chiamata JNI e caricare la libreria nativa, come evidenziato nel riquadro giallo della schermata seguente.

Come mostra la dichiarazione, la chiamata nativa restituisce una stringa Java che possiamo usare ovunque nel nostro file sorgente Java. Come illustrato nella schermata precedente, abbiamo modificato TextView in modo che visualizzi la stringa ottenuta dalla chiamata nativa. Questa operazione è evidenziata nel riquadro rosso.

Questo è un caso molto semplice per dichiarare e usare le chiamate JNI native nei file sorgente Java delle applicazioni Android. Useremo quindi lo strumento “javah” per generare gli stub dell'header JNI per il codice nativo e aggiungere o modificare il codice nativo in modo che sia conforme con le header JNI native.

3. Usare “javah” per generare gli stub dell'header JNI per il codice nativo

Dobbiamo ora modificare il nostro codice nativo in modo che sia conforme alla specifica della chiamata JNI. Anche “javah” ci aiuta a generare automaticamente gli stub appropriati dell'header JNI in base ai file sorgente Java. Per generare le header lo strumento “javah” richiede file di classe Java compilati. Usiamo così lo strumento “ant” per generare rapidamente file di classe Java, come mostrato nella schermata sottostante (“ant debug”).

Usare “javah” per generare l'header jni come mostrato nella schermata (secondo riquadro giallo). Questa operazione creerà la directory “jni” e lo stub dell'header in base alla classe Java. La schermata seguente mostra lo stub dell'header nativa JNI generato.

Creare il corrispondente file sorgente C (“com_example_cpuid_CPUIdApp.c”) per l'header precedentemente generata. Qui di seguito è mostrato il listato del file sorgente:

Chiamiamo il codice nativo cpuid_parse e restituiamo il buffer analizzato come stringa JNI. Siamo ora pronti a compilare il codice nativo usando gli strumenti dell'NDK x86.

4. Compilare il codice nativo con l'NDK per x86

Per ulteriori informazioni sull'installazione e l'utilizzo dell'NDK per l'architettura Intel, si prega di fare riferimento alla sezione della comunità Android (http://software.intel.com/it-it/android/articles/android-ndk-for-intel-architecture) nel sito Web di Intel.

Gli strumenti dell'Android NDK usano un sistema di compilazione che, per compilare il codice nativo, richiede che nella cartella “jni” del progetto sia presente uno specifico file make Android personalizzato, “Android.mk”. Android.mk specifica tutti i file sorgente C/C++ nativi che devono essere compilati, le header e il tipo di compilazione (es. shared_library).

Qui di seguito è mostrato il listato make Android del nostro progetto (“jni/Android.mk”)

Questo è un semplice scenario con due file sorgente C in cui si specifica di compilare una libreria condivisa.

Possiamo ora inviare l'istruzione “ndk-build APP_ABI=x86” per compilare il codice nativo e generare la libreria condivisa. Il sistema di compilazione Android offre un file make supplementare, “Application.mk”, che possiamo usare per specificare ulteriori opzioni di configurazione. Se ad esempio specifichiamo nel file Application.mk tutte le architetture ABI supportate, ndk-build genererà le librerie condivise native destinate a tutte le architetture.

La schermata precedente mostra la compilazione riuscita del codice nativo per x86 e mostra anche la libreria condivisa che viene generata e installata. Siamo ora pronti a ricompilare la nostra applicazione Android da installare/eseguire sull'emulatore x86 o sul dispositivo di destinazione.

5. Ricompilare, installare ed eseguire l'applicazione Android NDK per l'architettura Intel

Possiamo usare “ant debug clean” per rimuovere i vecchi file di compilazione e inviare di nuovo il comando “ant debug” per avviare la compilazione completa del progetto Android. Usare “adb” per reinstallare l'applicazione sul dispositivo di destinazione o nell'emulatore x86, come mostrato nella schermata seguente.

La schermata seguente mostra l'icona dell'applicazione dentro l'emulatore x86 e il risultato dell'esecuzione dell'applicazione nell'emulatore x86.

Abbiamo creato correttamente, dall'inizio alla fine, un'applicazione Android basata su NDK.

Uso degli strumenti dell'NDK x86 per eseguire il porting verso dispositivi basati sull'architettura Intel di applicazioni NDK esistenti

Le applicazioni Android con codice nativo hanno in genere una struttura di progetto standard, con la cartella “jni” che contiene i file sorgente nativi e i corrispondenti file di compilazione Android.mk/Application.mk. Nella sezione precedente abbiamo visto un semplice esempio con codice sorgente nativo e il corrispondente file Android.mk.

Gli strumenti dell'Android NDK ci permettono di specificare in una volta sola tutte le architetture ABI di destinazione nel file Application.mk e generare automaticamente le librerie condivise native per tutte le destinazioni. Il sistema di compilazione Android inserirà automaticamente tutte le librerie native di destinazione all'interno del pacchetto APK e, al momento dell'installazione, il gestore dei pacchetti Android installerà solo la libreria nativa appropriata per l'architettura di destinazione.

Si può richiamare “ndk-build” oppure nel file Application.mk specificare

APP_ABI := all

OPPURE

APP_ABI := armeabi armeabi-v7a x86

Per ulteriori informazioni, fare riferimento a http://developer.android.com/sdk/ndk/index.html.

Per quanto riguarda il porting di un'applicazione Android esistente con codice nativo e che attualmente non è destinata all'architettura x86, il processo per modificare l'applicazione affinché supporti l'architettura Intel è semplice nella maggior parte dei casi (come descritto in precedenza), a meno che l'applicazione non usi costrutti o un linguaggio assembly specifici dell'architettura. Potrebbero anche incidere altri fattori, come l'allineamento della memoria o l'utilizzo di istruzioni specifiche della piattaforma. Per maggiori informazioni, fare riferimento a http://software.intel.com/it-it/android/articles/ndk-android-application-porting-methodologies.

Riepilogo

Questo articolo tratta della creazione e del porting di applicazioni Android basate su NDK per destinarle all'architettura Intel. Con una descrizione dettagliata della procedura abbiamo dimostrato il processo per creare dall'inizio alla fine un'applicazione basata sull'NDK che usi l'architettura Intel. Abbiamo anche descritto un semplice processo, reso disponibile dagli strumenti dell'NDK, per eseguire il porting di applicazioni Android basate su NDK esistenti per destinarle all'architettura Intel.

Avvisi

Intel è un marchio di Intel Corporation registrato negli Stati Uniti e in altri paesi

LE INFORMAZIONI CONTENUTE IN QUESTO DOCUMENTO SONO FORNITE IN ABBINAMENTO AI PRODOTTI INTEL. QUESTO DOCUMENTO NON CONCEDE ALCUNA LICENZA, IMPLICITA O ESPLICITA, MEDIANTE PRECLUSIONE O ALTRO, PER QUANTO RIGUARDA I DIRITTI DI PROPRIETÀ INTELLETTUALE. AD ECCEZIONE DI QUANTO STABILITO DAI TERMINI E DALLE CONDIZIONI DI VENDITA INTEL PER I PRODOTTI IN QUESTIONE, INTEL NON SI ASSUME ALCUNA RESPONSABILITÀ E DISCONOSCE QUALSIASI GARANZIA ESPRESSA O IMPLICITA RELATIVA ALLA VENDITA E/O ALL'UTILIZZO DI PRODOTTI INTEL, INCLUSA LA RESPONSABILITÀ O L'IDONEITÀ AD UNO SCOPO PARTICOLARE, LA COMMERCIABILITÀ O LA VIOLAZIONE DI BREVETTI, COPYRIGHT O ALTRI DIRITTI DI PROPRIETÀ INTELLETTUALE.

Una "Applicazione mission critical"è qualsiasi applicazione in cui i difetti del prodotto Intel potrebbero causare, direttamente o indirettamente, lesioni personali o decesso. QUALORA SI ACQUISTASSERO O UTILIZZASSERO PRODOTTI INTEL PER QUALSIASI APPLICAZIONE MISSION CRITICAL, È NECESSARIO INDENNIZZARE E SOLLEVARE INTEL E LE SUE SOCIETÀ CONTROLLATE, SUBAPPALTATORI E AFFILIATI E I RESPONSABILI, FUNZIONARI E DIPENDENTI DI CIASCUNA DI QUESTE ENTITÀ, DA QUALSIASI RESPONSABILITÀ PER EVENTUALI COSTI PER RECLAMI, DANNI, SPESE E SPESE LEGALI RAGIONEVOLI DERIVANTI, DIRETTAMENTE O INDIRETTAMENTE, DA QUALSIASI RESPONSABILITÀ DEL PRODOTTO, LESIONE PERSONALE O DECESSO CAUSATI IN QUALSIASI MODO DA TALE APPLICAZIONE MISSION CRITICAL, INDIPENDENTEMENTE DAL FATTO CHE INTEL O IL PROPRIO SUBAPPALTATORE ABBIA AGITO IN MODO NEGLIGENTE NELLA PROGETTAZIONE, FABBRICAZIONE O AVVERTENZE DEL PRODOTTO INTEL O DI QUALSIASI SUO COMPONENTE.

Intel può apportare modifiche alle specifiche e alle descrizioni dei prodotti in qualsiasi momento e senza preavviso. I progettisti non devono fare affidamento sull'assenza o sulle caratteristiche di qualunque funzione o sulle istruzioni contrassegnate come "riservate" o "non definite". Intel si riserva di definirle in futuro e non accetta alcuna responsabilità in caso di conflitti o incompatibilità derivanti da ogni loro modifica futura. Le informazioni sono soggette a modifica senza preavviso. Non finalizzare un progetto con queste informazioni.

I prodotti descritti in questo documento possono contenere errori o difetti di progettazione noti come "errata" che possono determinare l'errato funzionamento del prodotto, a differenza di quanto stabilito nelle relative specifiche pubblicate. Gli "errata" attualmente riconosciuti sono disponibili su richiesta.

Per ottenere le specifiche più recenti e prima di inoltrare l'ordine di prodotti, contattare l'ufficio vendite Intel di zona oppure il distributore di fiducia.

Le copie dei documenti con numero d'ordine citati in questo documento, o altra letteratura Intel, possono essere richieste telefonando al numero (USA) 1-800-548-4725 oppure visitando il sito: http://www.intel.com/design/literature.htm * Altri marchi e denominazioni potrebbero essere proprietà di terzi.

Copyright© 2012 Intel Corporation. Tutti i diritti riservati

Il processore Intel® Core™ M

$
0
0

Abstract

Intel sta introducendo il primo processore di 5ª generazione (dal nome in codice Broadwell) con il lancio di tre SKU nella famiglia di processori Intel® Core™ M. Il presente articolo, indirizzato agli sviluppatori, fornisce una visione approfondita del processore SOC multi-core a 64 bit e offre una panoramica delle tecnologie Intel® disponibili, inclusa Grafica Intel® HD 5300.

Caratteristiche principali del processori Intel Core M

La famiglia di processori Intel® Core™ M offre prestazioni migliori in un package più piccolo che richiede un consumo energetico e un sistema di raffreddamento ridotti (ideale per i design sottili e privi di ventola) con una maggiore durata della batteria e include:

  • Grafica Intel HD 5300 e Intel® Wireless Display 5.0
  • Intel Wireless-AC 7265 e supporto docking wireless (2015) con WiGig
  • Tecnologia Intel® Smart Sound
  • Tecnologia Intel® Platform Protection e altri sistemi di sicurezza

Riduzione delle dimensioni + Miglioramenti delle prestazioni = Riduzione del consumo energetico e del sistema di raffreddamento

Il processore Intel Core M è il primo ad essere realizzato con la tecnologia a 14 nm. La dimensione del chip è stata ridotta di oltre il 30%, anche se il numero di transistori è aumentato di oltre 300 milioni.

Il processore Intel Core M dispone di un contenitore fisico a consumo energetico ridotto, che produce meno calore. I tre SKU rilasciati nel quarto trimestre del 2014 sono realizzati per funzionare con soli 4,5 watt, che vuol dire che possono funzionare senza ventola!
Questi SKU forniscono ottime prestazioni soprattutto sui fattori di forma ultrasottili (inferiori a 9 mm), inclusi tablet e dispositivi 2 in 1.


Figure 1: Small Low Power Intel Core M Processor Comparisons

Il grafico sul lato sinistro della Figura 1 mostra
la diminuzione della potenza dissipata da 18 W 
nel 2010 a 4,5 W con il processore 
Intel Core M. È una riduzione di 4 voltein 4 anni
e una riduzione del 60% dal 2013

Sul lato destro della Figura 1, la
comparazione mostra le
dimensioni del processore di 4ª generazione
Intel® Core™ rispetto al nuovo
processore Intel Core M.
E nella riduzione del pacchetto
del 50%, Intel ha raggiunto
una riduzione del 25% nell'area dei componenti.

Più piccolo in tutte le dimensioni del processore Intel Core di 4ª generazione, 
il processore Intel Core M fornisce una CPU composta da due core con una cache da 4 MB.
Dotato di tecnologia Intel® Hyper-Threading, consente di eseguire quattro thread contemporaneamente.
Con tecnologia Intel® TurboBoost 2.0, i processori con frequenza dei core da 0,8 GHz
possono raggiungere 2,0 GHz, mentre con frequenza dei core da 1,1,
il processore Intel Core M 5Y70 può raggiungere 2,6 GHz.

 

Grazie a 1,3 miliardi di transistori che forniscono CPU, grafica, controller di memoria, audio e connettività in un unico package, non ci sarà alcuna perdita di prestazioni. Di fatto, i test di comparazione con la generazione precedente di processori Intel® Core™ i5-4320Y hanno mostrato miglioramenti significativi delle prestazioni (vedi Figura 3).

Tecnologie energetiche

In questo documento ci sono molte tecnologie Intel utilizzate per mantenere il consumo di energia al minimo.

  • La tecnologia Intel® Turbo Boost 2.0 monitora il consumo energetico che calcola
    la potenza dei core di processore e grafica e regola l'energia in modo
    che l'energia e le prestazioni migliorate vengano impiegate dove è necessario.
  • La tecnologia Enhanced Intel SpeedStep® con stati C C0,1,1E, 3 e da 6
    a 10 assicura uno stato di inattività a bassissimo consumo energetico.
    Quando è richiesta maggiore energia, il processore aumenta la tensione
    per eseguire una rapida transizione.
    Con Hyper-Threading abilitato, ciò si verifica al livello thread.
  • Il gestore del risparmio energetico è ottimizzato con l'utilizzo di X2 APIC e 
    PAIR (Power Aware Interrupt Routing) e controlla i core in modo da 
    non attivare quelli nel "sonno profondo".

Tutti gli altri componenti hanno migliorato le funzionalità della gestione del consumo energetico che sono incluse nelle loro rispettive sezioni riportate in basso.

Il resto del package

Il package Intel Core M condivide un chip con PCH a basso consumo con una limitazione dei consumi intelligente che supporta PCIe NAND, PCIe 2.0 (12 corsie a x1, x2 o x4) e aggiunge 2 porte USB 2.0 aggiuntive.

Il controller di memoria integrato supporta Intel® Fast Memory Access e Intel® Flex-Memory Access e riduce il consumo di energia utilizzando aggiornamenti automatici condizionati, il controllo dinamico dell'energia e disattivando la memoria di sistema inutilizzata tramite 4 modalità di spegnimento, supportando la RAM DDR3L o LPDDR3 a 1600 o 1333 divisa in 2 canali.

Grafica Intel® HD 5300

Come nuova aggiunta alla famiglia Grafica Intel HD, Grafica Intel HD 5300 inizia da una base di 100 MHz che ha un frequenza dinamica massima di 800 MHz (850 MHz su 5Y70). Con Intel® Quick Sync Video (codifica e post-elaborazione per video e applicazioni con grafica intensiva), la tecnologia Intel® InTru™ 3D, la tecnologia Intel® Clear Video HD e Intel® Flexible Display Interface (Intel® FDI), la Grafica Intel HD 5300 supporta 3 display (eDP/DP/HDMI). Con l'utilizzo del processore della famiglia GT2 (con 189 milioni di transistori), Grafica HD 5300 è dotata di 24 unità di ombreggiatura, 4 TMU e 1 ROP con supporto per DirectX* 11.1+, OpenGL* 4.2, OpenCLTM 2.0, Shader Model 5.0, e fornisce una risoluzione UltraHD (3840 × 2160) tramite HDMI a 24 Hz.

I test hanno dimostrato che è possibile convertire video HD utilizzando Cyberlink* MediaEsspresso* fino all'80% più velocemente rispetto alla precedente generazione di processori core i5 e che i giochi (3DMark* IceStorm Unlimited v 1.2.) vengono eseguiti con prestazioni fino al 40% più elevate. Eppure, i processori Intel Core M forniscono comunque una durata della batteria di 1,7 ora in più (basata sulla riproduzione di video in locale e una batteria di 35 WHr).

(Tutti i test sono stati effettuati su piattaforme di riferimento Intel con 4 GB Dual Channel LPDDR3-1600 (2× 2 GB) con SSD Intel da 160 GB SSD con Windows 8.1 Update RTM. Il core M utilizzava il BIOS v80.1, mentre il core i5-4302Y (generazione precedente) utilizzava il BIOS WTM137. Entrambe le generazioni utilizzavano il driver Grafica Intel® HD v. 15.36.3650 ed erano dotate di TDP a 4,5 W. Altre impostazioni: Gestione del consumo energetico del sistema: equilibrata, Wireless: attivo e connesso, Dimensioni stimate della batteria: 35 WHr).

È possibile una durata maggiore della batteria, in quanto Grafica Intel HD 5300 dispone di:

  • Tecnologia Intel® Display Power Savings (Intel DPST) 6.0, che riduce la retroilluminazione aumentando il contrasto e la luminosità.
  • Intel® Automatic Display Brightness, che utilizza un sensore sul pannello anteriore per regolare la luce dell'ambiente.
  • Tecnologia Intel® Seamless Display Refresh Rate (SDRRS), che diminuisce la frequenza di aggiornamento quando la batteria è in fase di esaurimento.
  • Intel® Rapid Memory Power Management (Intel® RMPM), che permette l'aggiornamento automatico della batteria da stati di alimentazione a basso consumo.
  • Rendering grafico in stato C (RC6), che modifica la linea di alimentazione in bassa tensione quando non è in corso alcuna attività.
  • Tecnologia Intel® Smart 2D Display (Intel® S2DDT), che riduce la lettura della memoria per l'aggiornamento del display (disponibile solo in modalità single-pipe e non utilizzabile con le applicazioni 3D).
  • Tecnologia Intel® Graphics Dynamic Frequency, che aumenta la frequenza e la tensione in base alle esigenze delle prestazioni.

Schede Intel® Wireless-AC7265 di 2ª generazione

La famiglia di processori Intel Core M introduce anche una WLAN più veloce (le prestazioni migliorano del 15-100%) con un contenitore fisico più piccolo del 70%, utilizzando il fattore di forma M.2 1216.

Rispetto a Intel® Dual Band Wireless-A7260, la AC7265 ha migliorato la qualità di collegamento, è dotato di una copertura più ampia, di supporto per più dispositivi e può trasmettere video a 1080p pur essendo più ecologica del 50% quando inattiva (4 mW) e del 30% quando attiva (8 mW durante la navigazione nel web).

Nota: Intel prevede di introdurre docking wireless con WiGig nella famiglia Intel Core M nel 2015.


Intel® Wireless Display 5

Questa nuova generazione di Intel® Wireless Display (nota come Intel® WiDi) supporta una risoluzione di 1920 × 1080p a 60 fps, un tempo di connessione ridotto (inferiore a 6 secondi) e una latenza di gioco ridotta (inferiore a 65 ms). 

Le tecnologie includono:

  • HDCP 2.2
  • Scaling adattivo e frame rate
  • UoIP per lo schermo touch a più punti tattili o controllo dei gesti
  • Intel® Update Manager integrato per semplificare l'aggiornamento dei driver
  • Supporto di tutti i formati a schermo intero DX9/DX11 con rilevamento della modalità gioco
  • Intel WiDi Remote incluso per la gestione di multifinestre su doppi schermi
  • Funzionalità aggiuntive in Intel Pro WiDi, dedicate all'utilizzo nelle sale per conferenze
  • DCM (modalità canale differente)
  • Schermo per la privacy
  • Isolamento WPAN
  • Maneggevolezza

Vedere anche Building Intel® WiDi Apps for UltrabookTM

Tecnologia Intel® Smart Sound

Con un nuovo DSP I2S più potente integrato nel PCH, la tecnologia Intel Smart Sound (Intel® SST) riduce la potenza della piattaforma con l'offload dei flussi audio elaborandoli dalla CPU host per la decodificazione di MP3/AAC, post-elaborazione Waves* o DTS* e attivazione vocale. Il codec I2S deve essere utilizzato per Intel SST.

Tecnologia di sicurezza che include Intel® Platform Protection

I sistemi con i processori Intel Core M sono dotati di funzioni di sicurezza avanzate, tra cui:

  • La tecnologia Intel® Virtualization (Intel® VT-d e Intel® VT-x con EPT) ottimizza l'utilizzo della memoria VM e consente garanzie di QoS
  • Standard di crittografia Intel® Advanced Encryption - Nuove istruzioni (Intel® AES-NI) - 6 istruzioni Intel® SSE per la sicurezza ad alte prestazioni
  • Intel® Secure Key - Generatore dinamico di cifre casuali
  • PCLMULQDQ (moltiplicazione carry-less), utilizzata spesso in crittografia
  • OS Guard
  • Execute Disable (ND) Bit
  • SMEP (Supervisor Mode Execution Protection) e SMAP (Supervisor Mode Access Protection)
  • Intel® Device Protection con Boot Guard
  • Tecnologia Intel® Active Management v10
Nota: in aggiunta, il processore Intel Core M 5Y70 supporta la tecnologia Intel vPro™, la tecnologia Intel® Trusted Execution (Intel® TXT) e Windows* Instant Go* (nota come Connected Standby).

 

Suggerimenti per gli sviluppatori

 

Considerare le seguenti funzionalità per lo sviluppo di applicazioni per la famiglia di processori Intel Core M.

  • Con la tecnologia Intel SpeedStep, utilizzare l'istruzione MWAIT e i sotto-stati per la maggior parte delle transizioni degli stati di alimentazione; per gli stati C1/C1E utilizzare l'istruzione HLT. Per ulteriori informazioni sugli stati C dei core, consultare il Volume 1 della scheda informativa di Intel Core M.

Altra documentazione e strumenti utili di Intel:

Informazioni sull'autore

Colleen Culbertson è un ingegnere di applicazioni per piattaforme nella Developer Relations Division, autore di articoli e di un blog nell'Intel® Developer Zone.

I test e le valutazioni sulle prestazioni vengono calcolati usando sistemi e/o componenti specifici e forniscono un'indicazione approssimativa delle prestazioni dei prodotti Intel misurate durante tali test. Qualsiasi differenza nell’hardware del sistema, nella progettazione del software o nella configurazione potrebbe influire sulle prestazioni effettive. Gli acquirenti sono tenuti a consultare altre fonti di informazioni per valutare le prestazioni dei sistemi o dei componenti che intendono acquistare. Per ulteriori informazioni sui test delle prestazioni dei prodotti Intel, visitare la pagina sulle Limitazioni dei benchmark delle prestazioni Intel..

Intel può apportare modifiche alle specifiche e alle descrizioni dei prodotti in qualsiasi momento e senza preavviso

Creazione e porting di applicazioni Android* basate su NDK per l'architettura Intel

$
0
0

Obiettivo

Quest'articolo è un'introduzione per principianti sulla creazione di applicazioni native Android* (basate su NDK) per i dispositivi basati sull'architettura Intel®. Tratta anche del porting verso i dispositivi basati sull'architettura Intel di applicazioni NDK Android originariamente create per dispositivi basati su altre architetture. Analizzeremo due scenari, uno per mostrare il processo completo di creazione di una semplice applicazione Android* basata su NDK e l'altro per dimostrare un semplice processo di porting di un'applicazione Android basata su NDK affinché sia utilizzabile su dispositivi basati sull'architettura Intel.

Indice

1. Introduzione

2. Creazione di un'applicazione Android basata su NDK per dispositivi basati sull'architettura Intel - Procedura dettagliata di una semplice applicazione

a. Creare un progetto Android predefinito
b. Richiamare il codice nativo dai file sorgente Java
c. Usare javah per generare gli stub dell'header JNI per il codice nativo
d. Compilare il codice nativo con l'NDK per l'architettura Intel
e. Ricompilare, installare ed eseguire l'applicazione Android NDK per l'architettura Intel

3. Uso degli strumenti dell'NDK x86 per eseguire il porting verso dispositivi basati sull'architettura Intel di applicazioni NDK esistenti

4. Riepilogo

Introduzione

È possibile incorporare codice nativo nelle applicazioni Android usando gli strumenti del Native Development Kit (NDK). Questo permette agli sviluppatori di riusare il codice legacy, codificare per l'hardware di basso livello o differenziare le applicazioni sfruttando funzioni che altrimenti non sarebbero ottimali o disponibili.

Questo articolo è un'introduzione elementare su come creare, dall'inizio alla fine, applicazioni basate su NDK per l'architettura Intel e include anche dei semplici casi di utilizzo per eseguire il porting di applicazioni esistenti basate su NDK verso dispositivi basati sull'architettura Intel. Sarà descritto dettagliatamente un semplice scenario di sviluppo di un'applicazione per dimostrare il processo.

Si presume che l'ambiente di sviluppo Android sia già installato, compresi l'Android SDK, l'Android NDK e l'emulatore x86 configurato per testare le applicazioni. Per ulteriori informazioni, si prega di fare riferimento alla sezione della comunità Android nel sito Web di Intel. Per mantenere un ambiente di sviluppo semplice, nella maggior parte dei casi si useranno strumenti della riga di comando Linux*.

Creazione di un'applicazione Android basata su NDK per dispositivi basati sull'architettura Intel - Procedura dettagliata di una semplice applicazione

Si presuma di avere del codice legacy che usa C e il linguaggio assembly per analizzare l'istruzione CPUID (per maggiori informazioni su CPUID, consultare http://it.wikipedia.org/wiki/CPUID*). Qui di seguito è il listato del file sorgente del nostro codice C “legacy” di esempio cpuid.c (che è solo a scopo dimostrativo).

Desideriamo richiamare cpuid_parse dalla nostra applicazione Android (solo a scopo dimostrativo; la funzione cpuid_parse prevede un buffer preallocato) e visualizzare l'output all'interno dell'applicazione.

Qui di seguito è descritta la procedura dettagliata per creare l'applicazione Android dall'inizio alla fine e usare il codice nativo legacy visto in precedenza.

1. Creare un progetto Android predefinito

Android SDK ha strumenti della riga di comando che consentono di generare una struttura di progetto predefinita per un'applicazione hello world tipica. Creeremo innanzitutto un progetto predefinito, quindi modificheremo i file sorgente Java in modo da poter aggiungere chiamate JNI e codice nativo.

Nella schermata precedente, abbiamo prima creato una directory chiamata labs/lab2 e usato lo strumento della riga di comando “android” per generare il progetto predefinito. Abbiamo specificato android-15 come livello di API e chiamato la nostra applicazione “CPUIdApp” con package com.example.cpuid.

Abbiamo quindi usato lo strumento della riga di comando “ant” per creare il progetto in modalità di debug e installare usando “adb” (o reinstallare se già esistente nell'emulatore e nella destinazione). Si presume che abbiate già un emulatore o un dispositivo collegato e che sia l'unico dispositivo che viene elencato nell'output del comando “adb devices”.

La schermata seguente mostra l'emulatore Android x86 con ICS dopo avere completato il processo precedente.

Facendo clic sull'applicazione, viene visualizzato l'output predefinito hello world dell'applicazione. Modificheremo ora l'applicazione per l'uso del codice nativo.

2. Richiamare il codice nativo dai file sorgente Java

Il progetto Android predefinito genera i file sorgente Java per un progetto hello world tipico con lo spazio dei nomi del pacchetto dato (es. com.example.cpuid). La schermata seguente mostra il codice sorgente generato per il file sorgente Java principale.

Per usare il codice nativo C/C++ nel nostro file sorgente Java, dobbiamo prima dichiarare la chiamata JNI e caricare la libreria nativa, come evidenziato nel riquadro giallo della schermata seguente.

Come mostra la dichiarazione, la chiamata nativa restituisce una stringa Java che possiamo usare ovunque nel nostro file sorgente Java. Come illustrato nella schermata precedente, abbiamo modificato TextView in modo che visualizzi la stringa ottenuta dalla chiamata nativa. Questa operazione è evidenziata nel riquadro rosso.

Questo è un caso molto semplice per dichiarare e usare le chiamate JNI native nei file sorgente Java delle applicazioni Android. Useremo quindi lo strumento “javah” per generare gli stub dell'header JNI per il codice nativo e aggiungere o modificare il codice nativo in modo che sia conforme con le header JNI native.

3. Usare “javah” per generare gli stub dell'header JNI per il codice nativo

Dobbiamo ora modificare il nostro codice nativo in modo che sia conforme alla specifica della chiamata JNI. Anche “javah” ci aiuta a generare automaticamente gli stub appropriati dell'header JNI in base ai file sorgente Java. Per generare le header lo strumento “javah” richiede file di classe Java compilati. Usiamo così lo strumento “ant” per generare rapidamente file di classe Java, come mostrato nella schermata sottostante (“ant debug”).

Usare “javah” per generare l'header jni come mostrato nella schermata (secondo riquadro giallo). Questa operazione creerà la directory “jni” e lo stub dell'header in base alla classe Java. La schermata seguente mostra lo stub dell'header nativa JNI generato.

Creare il corrispondente file sorgente C (“com_example_cpuid_CPUIdApp.c”) per l'header precedentemente generata. Qui di seguito è mostrato il listato del file sorgente:

Chiamiamo il codice nativo cpuid_parse e restituiamo il buffer analizzato come stringa JNI. Siamo ora pronti a compilare il codice nativo usando gli strumenti dell'NDK x86.

4. Compilare il codice nativo con l'NDK per x86

Per ulteriori informazioni sull'installazione e l'utilizzo dell'NDK per l'architettura Intel, si prega di fare riferimento alla sezione della comunità Android (http://software.intel.com/it-it/android/articles/android-ndk-for-intel-architecture) nel sito Web di Intel.

Gli strumenti dell'Android NDK usano un sistema di compilazione che, per compilare il codice nativo, richiede che nella cartella “jni” del progetto sia presente uno specifico file make Android personalizzato, “Android.mk”. Android.mk specifica tutti i file sorgente C/C++ nativi che devono essere compilati, le header e il tipo di compilazione (es. shared_library).

Qui di seguito è mostrato il listato make Android del nostro progetto (“jni/Android.mk”)

Questo è un semplice scenario con due file sorgente C in cui si specifica di compilare una libreria condivisa.

Possiamo ora inviare l'istruzione “ndk-build APP_ABI=x86” per compilare il codice nativo e generare la libreria condivisa. Il sistema di compilazione Android offre un file make supplementare, “Application.mk”, che possiamo usare per specificare ulteriori opzioni di configurazione. Se ad esempio specifichiamo nel file Application.mk tutte le architetture ABI supportate, ndk-build genererà le librerie condivise native destinate a tutte le architetture.

La schermata precedente mostra la compilazione riuscita del codice nativo per x86 e mostra anche la libreria condivisa che viene generata e installata. Siamo ora pronti a ricompilare la nostra applicazione Android da installare/eseguire sull'emulatore x86 o sul dispositivo di destinazione.

5. Ricompilare, installare ed eseguire l'applicazione Android NDK per l'architettura Intel

Possiamo usare “ant debug clean” per rimuovere i vecchi file di compilazione e inviare di nuovo il comando “ant debug” per avviare la compilazione completa del progetto Android. Usare “adb” per reinstallare l'applicazione sul dispositivo di destinazione o nell'emulatore x86, come mostrato nella schermata seguente.

La schermata seguente mostra l'icona dell'applicazione dentro l'emulatore x86 e il risultato dell'esecuzione dell'applicazione nell'emulatore x86.

Abbiamo creato correttamente, dall'inizio alla fine, un'applicazione Android basata su NDK.

Uso degli strumenti dell'NDK x86 per eseguire il porting verso dispositivi basati sull'architettura Intel di applicazioni NDK esistenti

Le applicazioni Android con codice nativo hanno in genere una struttura di progetto standard, con la cartella “jni” che contiene i file sorgente nativi e i corrispondenti file di compilazione Android.mk/Application.mk. Nella sezione precedente abbiamo visto un semplice esempio con codice sorgente nativo e il corrispondente file Android.mk.

Gli strumenti dell'Android NDK ci permettono di specificare in una volta sola tutte le architetture ABI di destinazione nel file Application.mk e generare automaticamente le librerie condivise native per tutte le destinazioni. Il sistema di compilazione Android inserirà automaticamente tutte le librerie native di destinazione all'interno del pacchetto APK e, al momento dell'installazione, il gestore dei pacchetti Android installerà solo la libreria nativa appropriata per l'architettura di destinazione.

Si può richiamare “ndk-build” oppure nel file Application.mk specificare

APP_ABI := all

OPPURE

APP_ABI := armeabi armeabi-v7a x86

Per ulteriori informazioni, fare riferimento a http://developer.android.com/sdk/ndk/index.html.

Per quanto riguarda il porting di un'applicazione Android esistente con codice nativo e che attualmente non è destinata all'architettura x86, il processo per modificare l'applicazione affinché supporti l'architettura Intel è semplice nella maggior parte dei casi (come descritto in precedenza), a meno che l'applicazione non usi costrutti o un linguaggio assembly specifici dell'architettura. Potrebbero anche incidere altri fattori, come l'allineamento della memoria o l'utilizzo di istruzioni specifiche della piattaforma. Per maggiori informazioni, fare riferimento a http://software.intel.com/it-it/android/articles/ndk-android-application-porting-methodologies.

Riepilogo

Questo articolo tratta della creazione e del porting di applicazioni Android basate su NDK per destinarle all'architettura Intel. Con una descrizione dettagliata della procedura abbiamo dimostrato il processo per creare dall'inizio alla fine un'applicazione basata sull'NDK che usi l'architettura Intel. Abbiamo anche descritto un semplice processo, reso disponibile dagli strumenti dell'NDK, per eseguire il porting di applicazioni Android basate su NDK esistenti per destinarle all'architettura Intel.

Avvisi

Intel è un marchio di Intel Corporation registrato negli Stati Uniti e in altri paesi

LE INFORMAZIONI CONTENUTE IN QUESTO DOCUMENTO SONO FORNITE IN ABBINAMENTO AI PRODOTTI INTEL. QUESTO DOCUMENTO NON CONCEDE ALCUNA LICENZA, IMPLICITA O ESPLICITA, MEDIANTE PRECLUSIONE O ALTRO, PER QUANTO RIGUARDA I DIRITTI DI PROPRIETÀ INTELLETTUALE. AD ECCEZIONE DI QUANTO STABILITO DAI TERMINI E DALLE CONDIZIONI DI VENDITA INTEL PER I PRODOTTI IN QUESTIONE, INTEL NON SI ASSUME ALCUNA RESPONSABILITÀ E DISCONOSCE QUALSIASI GARANZIA ESPRESSA O IMPLICITA RELATIVA ALLA VENDITA E/O ALL'UTILIZZO DI PRODOTTI INTEL, INCLUSA LA RESPONSABILITÀ O L'IDONEITÀ AD UNO SCOPO PARTICOLARE, LA COMMERCIABILITÀ O LA VIOLAZIONE DI BREVETTI, COPYRIGHT O ALTRI DIRITTI DI PROPRIETÀ INTELLETTUALE.

Una "Applicazione mission critical"è qualsiasi applicazione in cui i difetti del prodotto Intel potrebbero causare, direttamente o indirettamente, lesioni personali o decesso. QUALORA SI ACQUISTASSERO O UTILIZZASSERO PRODOTTI INTEL PER QUALSIASI APPLICAZIONE MISSION CRITICAL, È NECESSARIO INDENNIZZARE E SOLLEVARE INTEL E LE SUE SOCIETÀ CONTROLLATE, SUBAPPALTATORI E AFFILIATI E I RESPONSABILI, FUNZIONARI E DIPENDENTI DI CIASCUNA DI QUESTE ENTITÀ, DA QUALSIASI RESPONSABILITÀ PER EVENTUALI COSTI PER RECLAMI, DANNI, SPESE E SPESE LEGALI RAGIONEVOLI DERIVANTI, DIRETTAMENTE O INDIRETTAMENTE, DA QUALSIASI RESPONSABILITÀ DEL PRODOTTO, LESIONE PERSONALE O DECESSO CAUSATI IN QUALSIASI MODO DA TALE APPLICAZIONE MISSION CRITICAL, INDIPENDENTEMENTE DAL FATTO CHE INTEL O IL PROPRIO SUBAPPALTATORE ABBIA AGITO IN MODO NEGLIGENTE NELLA PROGETTAZIONE, FABBRICAZIONE O AVVERTENZE DEL PRODOTTO INTEL O DI QUALSIASI SUO COMPONENTE.

Intel può apportare modifiche alle specifiche e alle descrizioni dei prodotti in qualsiasi momento e senza preavviso. I progettisti non devono fare affidamento sull'assenza o sulle caratteristiche di qualunque funzione o sulle istruzioni contrassegnate come "riservate" o "non definite". Intel si riserva di definirle in futuro e non accetta alcuna responsabilità in caso di conflitti o incompatibilità derivanti da ogni loro modifica futura. Le informazioni sono soggette a modifica senza preavviso. Non finalizzare un progetto con queste informazioni.

I prodotti descritti in questo documento possono contenere errori o difetti di progettazione noti come "errata" che possono determinare l'errato funzionamento del prodotto, a differenza di quanto stabilito nelle relative specifiche pubblicate. Gli "errata" attualmente riconosciuti sono disponibili su richiesta.

Per ottenere le specifiche più recenti e prima di inoltrare l'ordine di prodotti, contattare l'ufficio vendite Intel di zona oppure il distributore di fiducia.

Le copie dei documenti con numero d'ordine citati in questo documento, o altra letteratura Intel, possono essere richieste telefonando al numero (USA) 1-800-548-4725 oppure visitando il sito: http://www.intel.com/design/literature.htm * Altri marchi e denominazioni potrebbero essere proprietà di terzi.

Copyright© 2012 Intel Corporation. Tutti i diritti riservati

Viewing all 183 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>